xref: /openbmc/u-boot/lib/rbtree.c (revision 78acc472)
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 <ubi_uboot.h>
24 #include <linux/rbtree.h>
25 
26 static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
27 {
28 	struct rb_node *right = node->rb_right;
29 	struct rb_node *parent = rb_parent(node);
30 
31 	if ((node->rb_right = right->rb_left))
32 		rb_set_parent(right->rb_left, node);
33 	right->rb_left = node;
34 
35 	rb_set_parent(right, parent);
36 
37 	if (parent)
38 	{
39 		if (node == parent->rb_left)
40 			parent->rb_left = right;
41 		else
42 			parent->rb_right = right;
43 	}
44 	else
45 		root->rb_node = right;
46 	rb_set_parent(node, right);
47 }
48 
49 static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
50 {
51 	struct rb_node *left = node->rb_left;
52 	struct rb_node *parent = rb_parent(node);
53 
54 	if ((node->rb_left = left->rb_right))
55 		rb_set_parent(left->rb_right, node);
56 	left->rb_right = node;
57 
58 	rb_set_parent(left, parent);
59 
60 	if (parent)
61 	{
62 		if (node == parent->rb_right)
63 			parent->rb_right = left;
64 		else
65 			parent->rb_left = left;
66 	}
67 	else
68 		root->rb_node = left;
69 	rb_set_parent(node, left);
70 }
71 
72 void rb_insert_color(struct rb_node *node, struct rb_root *root)
73 {
74 	struct rb_node *parent, *gparent;
75 
76 	while ((parent = rb_parent(node)) && rb_is_red(parent))
77 	{
78 		gparent = rb_parent(parent);
79 
80 		if (parent == gparent->rb_left)
81 		{
82 			{
83 				register struct rb_node *uncle = gparent->rb_right;
84 				if (uncle && rb_is_red(uncle))
85 				{
86 					rb_set_black(uncle);
87 					rb_set_black(parent);
88 					rb_set_red(gparent);
89 					node = gparent;
90 					continue;
91 				}
92 			}
93 
94 			if (parent->rb_right == node)
95 			{
96 				register struct rb_node *tmp;
97 				__rb_rotate_left(parent, root);
98 				tmp = parent;
99 				parent = node;
100 				node = tmp;
101 			}
102 
103 			rb_set_black(parent);
104 			rb_set_red(gparent);
105 			__rb_rotate_right(gparent, root);
106 		} else {
107 			{
108 				register struct rb_node *uncle = gparent->rb_left;
109 				if (uncle && rb_is_red(uncle))
110 				{
111 					rb_set_black(uncle);
112 					rb_set_black(parent);
113 					rb_set_red(gparent);
114 					node = gparent;
115 					continue;
116 				}
117 			}
118 
119 			if (parent->rb_left == node)
120 			{
121 				register struct rb_node *tmp;
122 				__rb_rotate_right(parent, root);
123 				tmp = parent;
124 				parent = node;
125 				node = tmp;
126 			}
127 
128 			rb_set_black(parent);
129 			rb_set_red(gparent);
130 			__rb_rotate_left(gparent, root);
131 		}
132 	}
133 
134 	rb_set_black(root->rb_node);
135 }
136 
137 static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
138 			     struct rb_root *root)
139 {
140 	struct rb_node *other;
141 
142 	while ((!node || rb_is_black(node)) && node != root->rb_node)
143 	{
144 		if (parent->rb_left == node)
145 		{
146 			other = parent->rb_right;
147 			if (rb_is_red(other))
148 			{
149 				rb_set_black(other);
150 				rb_set_red(parent);
151 				__rb_rotate_left(parent, root);
152 				other = parent->rb_right;
153 			}
154 			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
155 			    (!other->rb_right || rb_is_black(other->rb_right)))
156 			{
157 				rb_set_red(other);
158 				node = parent;
159 				parent = rb_parent(node);
160 			}
161 			else
162 			{
163 				if (!other->rb_right || rb_is_black(other->rb_right))
164 				{
165 					struct rb_node *o_left;
166 					if ((o_left = other->rb_left))
167 						rb_set_black(o_left);
168 					rb_set_red(other);
169 					__rb_rotate_right(other, root);
170 					other = parent->rb_right;
171 				}
172 				rb_set_color(other, rb_color(parent));
173 				rb_set_black(parent);
174 				if (other->rb_right)
175 					rb_set_black(other->rb_right);
176 				__rb_rotate_left(parent, root);
177 				node = root->rb_node;
178 				break;
179 			}
180 		}
181 		else
182 		{
183 			other = parent->rb_left;
184 			if (rb_is_red(other))
185 			{
186 				rb_set_black(other);
187 				rb_set_red(parent);
188 				__rb_rotate_right(parent, root);
189 				other = parent->rb_left;
190 			}
191 			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
192 			    (!other->rb_right || rb_is_black(other->rb_right)))
193 			{
194 				rb_set_red(other);
195 				node = parent;
196 				parent = rb_parent(node);
197 			}
198 			else
199 			{
200 				if (!other->rb_left || rb_is_black(other->rb_left))
201 				{
202 					register struct rb_node *o_right;
203 					if ((o_right = other->rb_right))
204 						rb_set_black(o_right);
205 					rb_set_red(other);
206 					__rb_rotate_left(other, root);
207 					other = parent->rb_left;
208 				}
209 				rb_set_color(other, rb_color(parent));
210 				rb_set_black(parent);
211 				if (other->rb_left)
212 					rb_set_black(other->rb_left);
213 				__rb_rotate_right(parent, root);
214 				node = root->rb_node;
215 				break;
216 			}
217 		}
218 	}
219 	if (node)
220 		rb_set_black(node);
221 }
222 
223 void rb_erase(struct rb_node *node, struct rb_root *root)
224 {
225 	struct rb_node *child, *parent;
226 	int color;
227 
228 	if (!node->rb_left)
229 		child = node->rb_right;
230 	else if (!node->rb_right)
231 		child = node->rb_left;
232 	else
233 	{
234 		struct rb_node *old = node, *left;
235 
236 		node = node->rb_right;
237 		while ((left = node->rb_left) != NULL)
238 			node = left;
239 		child = node->rb_right;
240 		parent = rb_parent(node);
241 		color = rb_color(node);
242 
243 		if (child)
244 			rb_set_parent(child, parent);
245 		if (parent == old) {
246 			parent->rb_right = child;
247 			parent = node;
248 		} else
249 			parent->rb_left = child;
250 
251 		node->rb_parent_color = old->rb_parent_color;
252 		node->rb_right = old->rb_right;
253 		node->rb_left = old->rb_left;
254 
255 		if (rb_parent(old))
256 		{
257 			if (rb_parent(old)->rb_left == old)
258 				rb_parent(old)->rb_left = node;
259 			else
260 				rb_parent(old)->rb_right = node;
261 		} else
262 			root->rb_node = node;
263 
264 		rb_set_parent(old->rb_left, node);
265 		if (old->rb_right)
266 			rb_set_parent(old->rb_right, node);
267 		goto color;
268 	}
269 
270 	parent = rb_parent(node);
271 	color = rb_color(node);
272 
273 	if (child)
274 		rb_set_parent(child, parent);
275 	if (parent)
276 	{
277 		if (parent->rb_left == node)
278 			parent->rb_left = child;
279 		else
280 			parent->rb_right = child;
281 	}
282 	else
283 		root->rb_node = child;
284 
285  color:
286 	if (color == RB_BLACK)
287 		__rb_erase_color(child, parent, root);
288 }
289 
290 /*
291  * This function returns the first node (in sort order) of the tree.
292  */
293 struct rb_node *rb_first(struct rb_root *root)
294 {
295 	struct rb_node	*n;
296 
297 	n = root->rb_node;
298 	if (!n)
299 		return NULL;
300 	while (n->rb_left)
301 		n = n->rb_left;
302 	return n;
303 }
304 
305 struct rb_node *rb_last(struct rb_root *root)
306 {
307 	struct rb_node	*n;
308 
309 	n = root->rb_node;
310 	if (!n)
311 		return NULL;
312 	while (n->rb_right)
313 		n = n->rb_right;
314 	return n;
315 }
316 
317 struct rb_node *rb_next(struct rb_node *node)
318 {
319 	struct rb_node *parent;
320 
321 	if (rb_parent(node) == node)
322 		return NULL;
323 
324 	/* If we have a right-hand child, go down and then left as far
325 	   as we can. */
326 	if (node->rb_right) {
327 		node = node->rb_right;
328 		while (node->rb_left)
329 			node=node->rb_left;
330 		return node;
331 	}
332 
333 	/* No right-hand children.  Everything down and left is
334 	   smaller than us, so any 'next' node must be in the general
335 	   direction of our parent. Go up the tree; any time the
336 	   ancestor is a right-hand child of its parent, keep going
337 	   up. First time it's a left-hand child of its parent, said
338 	   parent is our 'next' node. */
339 	while ((parent = rb_parent(node)) && node == parent->rb_right)
340 		node = parent;
341 
342 	return parent;
343 }
344 
345 struct rb_node *rb_prev(struct rb_node *node)
346 {
347 	struct rb_node *parent;
348 
349 	if (rb_parent(node) == node)
350 		return NULL;
351 
352 	/* If we have a left-hand child, go down and then right as far
353 	   as we can. */
354 	if (node->rb_left) {
355 		node = node->rb_left;
356 		while (node->rb_right)
357 			node=node->rb_right;
358 		return node;
359 	}
360 
361 	/* No left-hand children. Go up till we find an ancestor which
362 	   is a right-hand child of its parent */
363 	while ((parent = rb_parent(node)) && node == parent->rb_left)
364 		node = parent;
365 
366 	return parent;
367 }
368 
369 void rb_replace_node(struct rb_node *victim, struct rb_node *new,
370 		     struct rb_root *root)
371 {
372 	struct rb_node *parent = rb_parent(victim);
373 
374 	/* Set the surrounding nodes to point to the replacement */
375 	if (parent) {
376 		if (victim == parent->rb_left)
377 			parent->rb_left = new;
378 		else
379 			parent->rb_right = new;
380 	} else {
381 		root->rb_node = new;
382 	}
383 	if (victim->rb_left)
384 		rb_set_parent(victim->rb_left, new);
385 	if (victim->rb_right)
386 		rb_set_parent(victim->rb_right, new);
387 
388 	/* Copy the pointers/colour from the victim to the replacement */
389 	*new = *victim;
390 }
391