[PATCH] m68k: bitops update [3/20]
[linux-2.6/history.git] / lib / rbtree.c
blobbed359bd4a92805eac07b7da940cbc1ead4acf1f
1 /*
2 Red Black Trees
3 (C) 1999 Andrea Arcangeli <andrea@suse.de>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 linux/lib/rbtree.c
22 #include <linux/rbtree.h>
23 #include <linux/module.h>
25 static void __rb_rotate_left(rb_node_t * node, rb_root_t * root)
27 rb_node_t * right = node->rb_right;
29 if ((node->rb_right = right->rb_left))
30 right->rb_left->rb_parent = node;
31 right->rb_left = node;
33 if ((right->rb_parent = node->rb_parent))
35 if (node == node->rb_parent->rb_left)
36 node->rb_parent->rb_left = right;
37 else
38 node->rb_parent->rb_right = right;
40 else
41 root->rb_node = right;
42 node->rb_parent = right;
45 static void __rb_rotate_right(rb_node_t * node, rb_root_t * root)
47 rb_node_t * left = node->rb_left;
49 if ((node->rb_left = left->rb_right))
50 left->rb_right->rb_parent = node;
51 left->rb_right = node;
53 if ((left->rb_parent = node->rb_parent))
55 if (node == node->rb_parent->rb_right)
56 node->rb_parent->rb_right = left;
57 else
58 node->rb_parent->rb_left = left;
60 else
61 root->rb_node = left;
62 node->rb_parent = left;
65 void rb_insert_color(rb_node_t * node, rb_root_t * root)
67 rb_node_t * parent, * gparent;
69 while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
71 gparent = parent->rb_parent;
73 if (parent == gparent->rb_left)
76 register rb_node_t * uncle = gparent->rb_right;
77 if (uncle && uncle->rb_color == RB_RED)
79 uncle->rb_color = RB_BLACK;
80 parent->rb_color = RB_BLACK;
81 gparent->rb_color = RB_RED;
82 node = gparent;
83 continue;
87 if (parent->rb_right == node)
89 register rb_node_t * tmp;
90 __rb_rotate_left(parent, root);
91 tmp = parent;
92 parent = node;
93 node = tmp;
96 parent->rb_color = RB_BLACK;
97 gparent->rb_color = RB_RED;
98 __rb_rotate_right(gparent, root);
99 } else {
101 register rb_node_t * uncle = gparent->rb_left;
102 if (uncle && uncle->rb_color == RB_RED)
104 uncle->rb_color = RB_BLACK;
105 parent->rb_color = RB_BLACK;
106 gparent->rb_color = RB_RED;
107 node = gparent;
108 continue;
112 if (parent->rb_left == node)
114 register rb_node_t * tmp;
115 __rb_rotate_right(parent, root);
116 tmp = parent;
117 parent = node;
118 node = tmp;
121 parent->rb_color = RB_BLACK;
122 gparent->rb_color = RB_RED;
123 __rb_rotate_left(gparent, root);
127 root->rb_node->rb_color = RB_BLACK;
129 EXPORT_SYMBOL(rb_insert_color);
131 static void __rb_erase_color(rb_node_t * node, rb_node_t * parent,
132 rb_root_t * root)
134 rb_node_t * other;
136 while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
138 if (parent->rb_left == node)
140 other = parent->rb_right;
141 if (other->rb_color == RB_RED)
143 other->rb_color = RB_BLACK;
144 parent->rb_color = RB_RED;
145 __rb_rotate_left(parent, root);
146 other = parent->rb_right;
148 if ((!other->rb_left ||
149 other->rb_left->rb_color == RB_BLACK)
150 && (!other->rb_right ||
151 other->rb_right->rb_color == RB_BLACK))
153 other->rb_color = RB_RED;
154 node = parent;
155 parent = node->rb_parent;
157 else
159 if (!other->rb_right ||
160 other->rb_right->rb_color == RB_BLACK)
162 register rb_node_t * o_left;
163 if ((o_left = other->rb_left))
164 o_left->rb_color = RB_BLACK;
165 other->rb_color = RB_RED;
166 __rb_rotate_right(other, root);
167 other = parent->rb_right;
169 other->rb_color = parent->rb_color;
170 parent->rb_color = RB_BLACK;
171 if (other->rb_right)
172 other->rb_right->rb_color = RB_BLACK;
173 __rb_rotate_left(parent, root);
174 node = root->rb_node;
175 break;
178 else
180 other = parent->rb_left;
181 if (other->rb_color == RB_RED)
183 other->rb_color = RB_BLACK;
184 parent->rb_color = RB_RED;
185 __rb_rotate_right(parent, root);
186 other = parent->rb_left;
188 if ((!other->rb_left ||
189 other->rb_left->rb_color == RB_BLACK)
190 && (!other->rb_right ||
191 other->rb_right->rb_color == RB_BLACK))
193 other->rb_color = RB_RED;
194 node = parent;
195 parent = node->rb_parent;
197 else
199 if (!other->rb_left ||
200 other->rb_left->rb_color == RB_BLACK)
202 register rb_node_t * o_right;
203 if ((o_right = other->rb_right))
204 o_right->rb_color = RB_BLACK;
205 other->rb_color = RB_RED;
206 __rb_rotate_left(other, root);
207 other = parent->rb_left;
209 other->rb_color = parent->rb_color;
210 parent->rb_color = RB_BLACK;
211 if (other->rb_left)
212 other->rb_left->rb_color = RB_BLACK;
213 __rb_rotate_right(parent, root);
214 node = root->rb_node;
215 break;
219 if (node)
220 node->rb_color = RB_BLACK;
223 void rb_erase(rb_node_t * node, rb_root_t * root)
225 rb_node_t * child, * parent;
226 int color;
228 if (!node->rb_left)
229 child = node->rb_right;
230 else if (!node->rb_right)
231 child = node->rb_left;
232 else
234 rb_node_t * old = node, * left;
236 node = node->rb_right;
237 while ((left = node->rb_left))
238 node = left;
239 child = node->rb_right;
240 parent = node->rb_parent;
241 color = node->rb_color;
243 if (child)
244 child->rb_parent = parent;
245 if (parent)
247 if (parent->rb_left == node)
248 parent->rb_left = child;
249 else
250 parent->rb_right = child;
252 else
253 root->rb_node = child;
255 if (node->rb_parent == old)
256 parent = node;
257 node->rb_parent = old->rb_parent;
258 node->rb_color = old->rb_color;
259 node->rb_right = old->rb_right;
260 node->rb_left = old->rb_left;
262 if (old->rb_parent)
264 if (old->rb_parent->rb_left == old)
265 old->rb_parent->rb_left = node;
266 else
267 old->rb_parent->rb_right = node;
268 } else
269 root->rb_node = node;
271 old->rb_left->rb_parent = node;
272 if (old->rb_right)
273 old->rb_right->rb_parent = node;
274 goto color;
277 parent = node->rb_parent;
278 color = node->rb_color;
280 if (child)
281 child->rb_parent = parent;
282 if (parent)
284 if (parent->rb_left == node)
285 parent->rb_left = child;
286 else
287 parent->rb_right = child;
289 else
290 root->rb_node = child;
292 color:
293 if (color == RB_BLACK)
294 __rb_erase_color(child, parent, root);
296 EXPORT_SYMBOL(rb_erase);