xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/jffs2/kernel/rbtree.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*========================================================================
2*10465441SEvalZero //
3*10465441SEvalZero //      rbtree.c
4*10465441SEvalZero //
5*10465441SEvalZero //      Red Black tree implementation
6*10465441SEvalZero //
7*10465441SEvalZero //========================================================================
8*10465441SEvalZero // ####ECOSGPLCOPYRIGHTBEGIN####
9*10465441SEvalZero // -------------------------------------------
10*10465441SEvalZero // This file is part of eCos, the Embedded Configurable Operating System.
11*10465441SEvalZero // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
12*10465441SEvalZero //
13*10465441SEvalZero // eCos is free software; you can redistribute it and/or modify it under
14*10465441SEvalZero // the terms of the GNU General Public License as published by the Free
15*10465441SEvalZero // Software Foundation; either version 2 or (at your option) any later
16*10465441SEvalZero // version.
17*10465441SEvalZero //
18*10465441SEvalZero // eCos is distributed in the hope that it will be useful, but WITHOUT
19*10465441SEvalZero // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20*10465441SEvalZero // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21*10465441SEvalZero // for more details.
22*10465441SEvalZero //
23*10465441SEvalZero // You should have received a copy of the GNU General Public License
24*10465441SEvalZero // along with eCos; if not, write to the Free Software Foundation, Inc.,
25*10465441SEvalZero // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26*10465441SEvalZero //
27*10465441SEvalZero // As a special exception, if other files instantiate templates or use
28*10465441SEvalZero // macros or inline functions from this file, or you compile this file
29*10465441SEvalZero // and link it with other works to produce a work based on this file,
30*10465441SEvalZero // this file does not by itself cause the resulting work to be covered by
31*10465441SEvalZero // the GNU General Public License. However the source code for this file
32*10465441SEvalZero // must still be made available in accordance with section (3) of the GNU
33*10465441SEvalZero // General Public License v2.
34*10465441SEvalZero //
35*10465441SEvalZero // This exception does not invalidate any other reasons why a work based
36*10465441SEvalZero // on this file might be covered by the GNU General Public License.
37*10465441SEvalZero // -------------------------------------------
38*10465441SEvalZero // ####ECOSGPLCOPYRIGHTEND####
39*10465441SEvalZero //========================================================================
40*10465441SEvalZero //#####DESCRIPTIONBEGIN####
41*10465441SEvalZero //
42*10465441SEvalZero // Author(s):     Niels Provos/OpenBSD
43*10465441SEvalZero // Contributors:  dwmw2
44*10465441SEvalZero // Date:          2003-01-21
45*10465441SEvalZero // Purpose:       This file provides an implementation of red-black trees.
46*10465441SEvalZero // Description:   Derived from OpenBSD src/sys/sys/tree.h
47*10465441SEvalZero // Usage:
48*10465441SEvalZero //
49*10465441SEvalZero //####DESCRIPTIONEND####
50*10465441SEvalZero //
51*10465441SEvalZero //======================================================================
52*10465441SEvalZero */
53*10465441SEvalZero 
54*10465441SEvalZero /*	$OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $	*/
55*10465441SEvalZero /*
56*10465441SEvalZero  * Copyright 2002 Niels Provos <[email protected]>
57*10465441SEvalZero  * All rights reserved.
58*10465441SEvalZero  *
59*10465441SEvalZero  * Redistribution and use in source and binary forms, with or without
60*10465441SEvalZero  * modification, are permitted provided that the following conditions
61*10465441SEvalZero  * are met:
62*10465441SEvalZero  * 1. Redistributions of source code must retain the above copyright
63*10465441SEvalZero  *    notice, this list of conditions and the following disclaimer.
64*10465441SEvalZero  * 2. Redistributions in binary form must reproduce the above copyright
65*10465441SEvalZero  *    notice, this list of conditions and the following disclaimer in the
66*10465441SEvalZero  *    documentation and/or other materials provided with the distribution.
67*10465441SEvalZero  *
68*10465441SEvalZero  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
69*10465441SEvalZero  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
70*10465441SEvalZero  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
71*10465441SEvalZero  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
72*10465441SEvalZero  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
73*10465441SEvalZero  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
74*10465441SEvalZero  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
75*10465441SEvalZero  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76*10465441SEvalZero  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
77*10465441SEvalZero  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78*10465441SEvalZero  */
79*10465441SEvalZero 
80*10465441SEvalZero /* Fields renamed to match Linux ones. */
81*10465441SEvalZero #include <linux/rbtree.h>
82*10465441SEvalZero 
83*10465441SEvalZero 
84*10465441SEvalZero #define RB_HEAD(head)		(head)->rb_node
85*10465441SEvalZero #define RB_LEFT(elm)		(elm)->rb_left
86*10465441SEvalZero #define RB_RIGHT(elm)		(elm)->rb_right
87*10465441SEvalZero #define RB_PARENT(elm)		(elm)->rb_parent
88*10465441SEvalZero #define RB_COLOR(elm)		(elm)->rb_color
89*10465441SEvalZero 
90*10465441SEvalZero 
91*10465441SEvalZero #define RB_SET(elm, parent) do {				\
92*10465441SEvalZero 	RB_PARENT(elm) = parent;				\
93*10465441SEvalZero 	RB_LEFT(elm) = RB_RIGHT(elm) = NULL;	\
94*10465441SEvalZero 	RB_COLOR(elm) = RB_RED;				\
95*10465441SEvalZero } while (0)
96*10465441SEvalZero 
97*10465441SEvalZero #define RB_SET_BLACKRED(black, red) do {			\
98*10465441SEvalZero 	RB_COLOR(black) = RB_BLACK;				\
99*10465441SEvalZero 	RB_COLOR(red) = RB_RED;					\
100*10465441SEvalZero } while (0)
101*10465441SEvalZero 
102*10465441SEvalZero #ifndef RB_AUGMENT
103*10465441SEvalZero #define RB_AUGMENT(x)
104*10465441SEvalZero #endif
105*10465441SEvalZero 
106*10465441SEvalZero #define RB_ROTATE_LEFT(head, elm, tmp) do {			\
107*10465441SEvalZero 	(tmp) = RB_RIGHT(elm);					\
108*10465441SEvalZero 	if ((RB_RIGHT(elm) = RB_LEFT(tmp))) {			\
109*10465441SEvalZero 		RB_PARENT(RB_LEFT(tmp)) = (elm);		\
110*10465441SEvalZero 	}							\
111*10465441SEvalZero 	RB_AUGMENT(elm);					\
112*10465441SEvalZero 	if ((RB_PARENT(tmp) = RB_PARENT(elm))) {		\
113*10465441SEvalZero 		if ((elm) == RB_LEFT(RB_PARENT(elm)))		\
114*10465441SEvalZero 			RB_LEFT(RB_PARENT(elm)) = (tmp);	\
115*10465441SEvalZero 		else						\
116*10465441SEvalZero 			RB_RIGHT(RB_PARENT(elm)) = (tmp);	\
117*10465441SEvalZero 	} else							\
118*10465441SEvalZero 		(head)->rb_node = (tmp);			\
119*10465441SEvalZero 	RB_LEFT(tmp) = (elm);					\
120*10465441SEvalZero 	RB_PARENT(elm) = (tmp);					\
121*10465441SEvalZero 	RB_AUGMENT(tmp);					\
122*10465441SEvalZero 	if ((RB_PARENT(tmp)))					\
123*10465441SEvalZero 		RB_AUGMENT(RB_PARENT(tmp));			\
124*10465441SEvalZero } while (0)
125*10465441SEvalZero 
126*10465441SEvalZero #define RB_ROTATE_RIGHT(head, elm, tmp) do {			\
127*10465441SEvalZero 	(tmp) = RB_LEFT(elm);					\
128*10465441SEvalZero 	if ((RB_LEFT(elm) = RB_RIGHT(tmp))) {			\
129*10465441SEvalZero 		RB_PARENT(RB_RIGHT(tmp)) = (elm);		\
130*10465441SEvalZero 	}							\
131*10465441SEvalZero 	RB_AUGMENT(elm);					\
132*10465441SEvalZero 	if ((RB_PARENT(tmp) = RB_PARENT(elm))) {		\
133*10465441SEvalZero 		if ((elm) == RB_LEFT(RB_PARENT(elm)))		\
134*10465441SEvalZero 			RB_LEFT(RB_PARENT(elm)) = (tmp);	\
135*10465441SEvalZero 		else						\
136*10465441SEvalZero 			RB_RIGHT(RB_PARENT(elm)) = (tmp);	\
137*10465441SEvalZero 	} else							\
138*10465441SEvalZero 		(head)->rb_node = (tmp);			\
139*10465441SEvalZero 	RB_RIGHT(tmp) = (elm);					\
140*10465441SEvalZero 	RB_PARENT(elm) = (tmp);					\
141*10465441SEvalZero 	RB_AUGMENT(tmp);					\
142*10465441SEvalZero 	if ((RB_PARENT(tmp)))					\
143*10465441SEvalZero 		RB_AUGMENT(RB_PARENT(tmp));			\
144*10465441SEvalZero } while(0)
145*10465441SEvalZero 
146*10465441SEvalZero /* Note args swapped to match Linux */
rb_insert_color(struct rb_node * elm,struct rb_root * head)147*10465441SEvalZero void rb_insert_color(struct rb_node *elm, struct rb_root *head)
148*10465441SEvalZero {
149*10465441SEvalZero 	struct rb_node *parent, *gparent, *tmp;
150*10465441SEvalZero 	while ((parent = RB_PARENT(elm)) &&
151*10465441SEvalZero 	    RB_COLOR(parent) == RB_RED) {
152*10465441SEvalZero 		gparent = RB_PARENT(parent);
153*10465441SEvalZero 		if (parent == RB_LEFT(gparent)) {
154*10465441SEvalZero 			tmp = RB_RIGHT(gparent);
155*10465441SEvalZero 			if (tmp && RB_COLOR(tmp) == RB_RED) {
156*10465441SEvalZero 				RB_COLOR(tmp) = RB_BLACK;
157*10465441SEvalZero 				RB_SET_BLACKRED(parent, gparent);
158*10465441SEvalZero 				elm = gparent;
159*10465441SEvalZero 				continue;
160*10465441SEvalZero 			}
161*10465441SEvalZero 			if (RB_RIGHT(parent) == elm) {
162*10465441SEvalZero 				RB_ROTATE_LEFT(head, parent, tmp);
163*10465441SEvalZero 				tmp = parent;
164*10465441SEvalZero 				parent = elm;
165*10465441SEvalZero 				elm = tmp;
166*10465441SEvalZero 			}
167*10465441SEvalZero 			RB_SET_BLACKRED(parent, gparent);
168*10465441SEvalZero 			RB_ROTATE_RIGHT(head, gparent, tmp);
169*10465441SEvalZero 		} else {
170*10465441SEvalZero 			tmp = RB_LEFT(gparent);
171*10465441SEvalZero 			if (tmp && RB_COLOR(tmp) == RB_RED) {
172*10465441SEvalZero 				RB_COLOR(tmp) = RB_BLACK;
173*10465441SEvalZero 				RB_SET_BLACKRED(parent, gparent);
174*10465441SEvalZero 				elm = gparent;
175*10465441SEvalZero 				continue;
176*10465441SEvalZero 			}
177*10465441SEvalZero 			if (RB_LEFT(parent) == elm) {
178*10465441SEvalZero 				RB_ROTATE_RIGHT(head, parent, tmp);
179*10465441SEvalZero 				tmp = parent;
180*10465441SEvalZero 				parent = elm;
181*10465441SEvalZero 				elm = tmp;
182*10465441SEvalZero 			}
183*10465441SEvalZero 			RB_SET_BLACKRED(parent, gparent);
184*10465441SEvalZero 			RB_ROTATE_LEFT(head, gparent, tmp);
185*10465441SEvalZero 		}
186*10465441SEvalZero 	}
187*10465441SEvalZero 	RB_COLOR(head->rb_node) = RB_BLACK;
188*10465441SEvalZero }
189*10465441SEvalZero 
190*10465441SEvalZero 
rb_remove_color(struct rb_root * head,struct rb_node * parent,struct rb_node * elm)191*10465441SEvalZero static void rb_remove_color(struct rb_root *head, struct rb_node *parent,
192*10465441SEvalZero 			    struct rb_node *elm)
193*10465441SEvalZero {
194*10465441SEvalZero 	struct rb_node *tmp;
195*10465441SEvalZero 	while ((elm == NULL || RB_COLOR(elm) == RB_BLACK) &&
196*10465441SEvalZero 	    elm != RB_HEAD(head)) {
197*10465441SEvalZero 		if (RB_LEFT(parent) == elm) {
198*10465441SEvalZero 			tmp = RB_RIGHT(parent);
199*10465441SEvalZero 			if (RB_COLOR(tmp) == RB_RED) {
200*10465441SEvalZero 				RB_SET_BLACKRED(tmp, parent);
201*10465441SEvalZero 				RB_ROTATE_LEFT(head, parent, tmp);
202*10465441SEvalZero 				tmp = RB_RIGHT(parent);
203*10465441SEvalZero 			}
204*10465441SEvalZero 			if ((RB_LEFT(tmp) == NULL ||
205*10465441SEvalZero 			    RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) &&
206*10465441SEvalZero 			    (RB_RIGHT(tmp) == NULL ||
207*10465441SEvalZero 			    RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) {
208*10465441SEvalZero 				RB_COLOR(tmp) = RB_RED;
209*10465441SEvalZero 				elm = parent;
210*10465441SEvalZero 				parent = RB_PARENT(elm);
211*10465441SEvalZero 			} else {
212*10465441SEvalZero 				if (RB_RIGHT(tmp) == NULL ||
213*10465441SEvalZero 				    RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK) {
214*10465441SEvalZero 					struct rb_node *oleft;
215*10465441SEvalZero 					if ((oleft = RB_LEFT(tmp)))
216*10465441SEvalZero 						RB_COLOR(oleft) = RB_BLACK;
217*10465441SEvalZero 					RB_COLOR(tmp) = RB_RED;
218*10465441SEvalZero 					RB_ROTATE_RIGHT(head, tmp, oleft);
219*10465441SEvalZero 					tmp = RB_RIGHT(parent);
220*10465441SEvalZero 				}
221*10465441SEvalZero 				RB_COLOR(tmp) = RB_COLOR(parent);
222*10465441SEvalZero 				RB_COLOR(parent) = RB_BLACK;
223*10465441SEvalZero 				if (RB_RIGHT(tmp))
224*10465441SEvalZero 					RB_COLOR(RB_RIGHT(tmp)) = RB_BLACK;
225*10465441SEvalZero 				RB_ROTATE_LEFT(head, parent, tmp);
226*10465441SEvalZero 				elm = RB_HEAD(head);
227*10465441SEvalZero 				break;
228*10465441SEvalZero 			}
229*10465441SEvalZero 		} else {
230*10465441SEvalZero 			tmp = RB_LEFT(parent);
231*10465441SEvalZero 			if (RB_COLOR(tmp) == RB_RED) {
232*10465441SEvalZero 				RB_SET_BLACKRED(tmp, parent);
233*10465441SEvalZero 				RB_ROTATE_RIGHT(head, parent, tmp);
234*10465441SEvalZero 				tmp = RB_LEFT(parent);
235*10465441SEvalZero 			}
236*10465441SEvalZero 			if ((RB_LEFT(tmp) == NULL ||
237*10465441SEvalZero 			    RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) &&
238*10465441SEvalZero 			    (RB_RIGHT(tmp) == NULL ||
239*10465441SEvalZero 			    RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) {
240*10465441SEvalZero 				RB_COLOR(tmp) = RB_RED;
241*10465441SEvalZero 				elm = parent;
242*10465441SEvalZero 				parent = RB_PARENT(elm);
243*10465441SEvalZero 			} else {
244*10465441SEvalZero 				if (RB_LEFT(tmp) == NULL ||
245*10465441SEvalZero 				    RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) {
246*10465441SEvalZero 					struct rb_node *oright;
247*10465441SEvalZero 					if ((oright = RB_RIGHT(tmp)))
248*10465441SEvalZero 						RB_COLOR(oright) = RB_BLACK;
249*10465441SEvalZero 					RB_COLOR(tmp) = RB_RED;
250*10465441SEvalZero 					RB_ROTATE_LEFT(head, tmp, oright);
251*10465441SEvalZero 					tmp = RB_LEFT(parent);
252*10465441SEvalZero 				}
253*10465441SEvalZero 				RB_COLOR(tmp) = RB_COLOR(parent);
254*10465441SEvalZero 				RB_COLOR(parent) = RB_BLACK;
255*10465441SEvalZero 				if (RB_LEFT(tmp))
256*10465441SEvalZero 					RB_COLOR(RB_LEFT(tmp)) = RB_BLACK;
257*10465441SEvalZero 				RB_ROTATE_RIGHT(head, parent, tmp);
258*10465441SEvalZero 				elm = RB_HEAD(head);
259*10465441SEvalZero 				break;
260*10465441SEvalZero 			}
261*10465441SEvalZero 		}
262*10465441SEvalZero 	}
263*10465441SEvalZero 	if (elm)
264*10465441SEvalZero 		RB_COLOR(elm) = RB_BLACK;
265*10465441SEvalZero }
266*10465441SEvalZero 
267*10465441SEvalZero /* Note name changed. Guess why :) */
rb_erase(struct rb_node * elm,struct rb_root * head)268*10465441SEvalZero void rb_erase(struct rb_node *elm, struct rb_root *head)
269*10465441SEvalZero {
270*10465441SEvalZero 	struct rb_node *child, *parent, *old = elm;
271*10465441SEvalZero 	int color;
272*10465441SEvalZero 	if (RB_LEFT(elm) == NULL)
273*10465441SEvalZero 		child = RB_RIGHT(elm);
274*10465441SEvalZero 	else if (RB_RIGHT(elm) == NULL)
275*10465441SEvalZero 		child = RB_LEFT(elm);
276*10465441SEvalZero 	else {
277*10465441SEvalZero 		struct rb_node *left;
278*10465441SEvalZero 		elm = RB_RIGHT(elm);
279*10465441SEvalZero 		while ((left = RB_LEFT(elm)))
280*10465441SEvalZero 			elm = left;
281*10465441SEvalZero 		child = RB_RIGHT(elm);
282*10465441SEvalZero 		parent = RB_PARENT(elm);
283*10465441SEvalZero 		color = RB_COLOR(elm);
284*10465441SEvalZero 		if (child)
285*10465441SEvalZero 			RB_PARENT(child) = parent;
286*10465441SEvalZero 		if (parent) {
287*10465441SEvalZero 			if (RB_LEFT(parent) == elm)
288*10465441SEvalZero 				RB_LEFT(parent) = child;
289*10465441SEvalZero 			else
290*10465441SEvalZero 				RB_RIGHT(parent) = child;
291*10465441SEvalZero 			RB_AUGMENT(parent);
292*10465441SEvalZero 		} else
293*10465441SEvalZero 			RB_HEAD(head) = child;
294*10465441SEvalZero 		if (RB_PARENT(elm) == old)
295*10465441SEvalZero 			parent = elm;
296*10465441SEvalZero 		*(elm) = *(old);
297*10465441SEvalZero 		if (RB_PARENT(old)) {
298*10465441SEvalZero 			if (RB_LEFT(RB_PARENT(old)) == old)
299*10465441SEvalZero 				RB_LEFT(RB_PARENT(old)) = elm;
300*10465441SEvalZero 			else
301*10465441SEvalZero 				RB_RIGHT(RB_PARENT(old)) = elm;
302*10465441SEvalZero 			RB_AUGMENT(RB_PARENT(old));
303*10465441SEvalZero 		} else
304*10465441SEvalZero 			RB_HEAD(head) = elm;
305*10465441SEvalZero 		RB_PARENT(RB_LEFT(old)) = elm;
306*10465441SEvalZero 		if (RB_RIGHT(old))
307*10465441SEvalZero 			RB_PARENT(RB_RIGHT(old)) = elm;
308*10465441SEvalZero 		if (parent) {
309*10465441SEvalZero 			left = parent;
310*10465441SEvalZero 			do {
311*10465441SEvalZero 				RB_AUGMENT(left);
312*10465441SEvalZero 			} while ((left = RB_PARENT(left)));
313*10465441SEvalZero 		}
314*10465441SEvalZero 		goto color;
315*10465441SEvalZero 	}
316*10465441SEvalZero 	parent = RB_PARENT(elm);
317*10465441SEvalZero 	color = RB_COLOR(elm);
318*10465441SEvalZero 	if (child)
319*10465441SEvalZero 		RB_PARENT(child) = parent;
320*10465441SEvalZero 	if (parent) {
321*10465441SEvalZero 		if (RB_LEFT(parent) == elm)
322*10465441SEvalZero 			RB_LEFT(parent) = child;
323*10465441SEvalZero 		else
324*10465441SEvalZero 			RB_RIGHT(parent) = child;
325*10465441SEvalZero 		RB_AUGMENT(parent);
326*10465441SEvalZero 	} else
327*10465441SEvalZero 		RB_HEAD(head) = child;
328*10465441SEvalZero color:
329*10465441SEvalZero 	if (color == RB_BLACK)
330*10465441SEvalZero 		rb_remove_color(head, parent, child);
331*10465441SEvalZero }
332*10465441SEvalZero 
rb_next(struct rb_node * elm)333*10465441SEvalZero struct rb_node *rb_next(struct rb_node *elm)
334*10465441SEvalZero {
335*10465441SEvalZero 	if (RB_RIGHT(elm)) {
336*10465441SEvalZero 		elm = RB_RIGHT(elm);
337*10465441SEvalZero 		while (RB_LEFT(elm))
338*10465441SEvalZero 			elm = RB_LEFT(elm);
339*10465441SEvalZero 	} else {
340*10465441SEvalZero 		if (RB_PARENT(elm) &&
341*10465441SEvalZero 		    (elm == RB_LEFT(RB_PARENT(elm))))
342*10465441SEvalZero 			elm = RB_PARENT(elm);
343*10465441SEvalZero 		else {
344*10465441SEvalZero 			while (RB_PARENT(elm) &&
345*10465441SEvalZero 			    (elm == RB_RIGHT(RB_PARENT(elm))))
346*10465441SEvalZero 				elm = RB_PARENT(elm);
347*10465441SEvalZero 			elm = RB_PARENT(elm);
348*10465441SEvalZero 		}
349*10465441SEvalZero 	}
350*10465441SEvalZero 	return (elm);
351*10465441SEvalZero }
352*10465441SEvalZero 
rb_prev(struct rb_node * elm)353*10465441SEvalZero struct rb_node *rb_prev(struct rb_node *elm)
354*10465441SEvalZero {
355*10465441SEvalZero 	if (RB_LEFT(elm)) {
356*10465441SEvalZero 		elm = RB_LEFT(elm);
357*10465441SEvalZero 		while (RB_RIGHT(elm))
358*10465441SEvalZero 			elm = RB_RIGHT(elm);
359*10465441SEvalZero 	} else {
360*10465441SEvalZero 		if (RB_PARENT(elm) &&
361*10465441SEvalZero 		    (elm == RB_RIGHT(RB_PARENT(elm))))
362*10465441SEvalZero 			elm = RB_PARENT(elm);
363*10465441SEvalZero 		else {
364*10465441SEvalZero 			while (RB_PARENT(elm) &&
365*10465441SEvalZero 			    (elm == RB_LEFT(RB_PARENT(elm))))
366*10465441SEvalZero 				elm = RB_PARENT(elm);
367*10465441SEvalZero 			elm = RB_PARENT(elm);
368*10465441SEvalZero 		}
369*10465441SEvalZero 	}
370*10465441SEvalZero 	return (elm);
371*10465441SEvalZero }
372*10465441SEvalZero 
373*10465441SEvalZero /* These ones are lifted from Linux -- but that's OK because I
374*10465441SEvalZero    wrote them. dwmw2. */
rb_first(struct rb_root * root)375*10465441SEvalZero struct rb_node *rb_first(struct rb_root *root)
376*10465441SEvalZero {
377*10465441SEvalZero         struct rb_node  *n;
378*10465441SEvalZero 
379*10465441SEvalZero         n = root->rb_node;
380*10465441SEvalZero         if (!n)
381*10465441SEvalZero                 return 0;
382*10465441SEvalZero         while (n->rb_left)
383*10465441SEvalZero                 n = n->rb_left;
384*10465441SEvalZero         return n;
385*10465441SEvalZero }
386*10465441SEvalZero 
rb_replace_node(struct rb_node * victim,struct rb_node * new,struct rb_root * root)387*10465441SEvalZero void rb_replace_node(struct rb_node *victim, struct rb_node *new,
388*10465441SEvalZero                      struct rb_root *root)
389*10465441SEvalZero {
390*10465441SEvalZero         struct rb_node *parent = victim->rb_parent;
391*10465441SEvalZero 
392*10465441SEvalZero         /* Set the surrounding nodes to point to the replacement */
393*10465441SEvalZero         if (parent) {
394*10465441SEvalZero                 if (victim == parent->rb_left)
395*10465441SEvalZero                         parent->rb_left = new;
396*10465441SEvalZero                 else
397*10465441SEvalZero                         parent->rb_right = new;
398*10465441SEvalZero         } else {
399*10465441SEvalZero                 root->rb_node = new;
400*10465441SEvalZero         }
401*10465441SEvalZero         if (victim->rb_left)
402*10465441SEvalZero                 victim->rb_left->rb_parent = new;
403*10465441SEvalZero         if (victim->rb_right)
404*10465441SEvalZero                 victim->rb_right->rb_parent = new;
405*10465441SEvalZero 
406*10465441SEvalZero         /* Copy the pointers/colour from the victim to the replacement */
407*10465441SEvalZero         *new = *victim;
408*10465441SEvalZero }
409