1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker Red Black Trees
3*6a54128fSAndroid Build Coastguard Worker (C) 1999 Andrea Arcangeli <[email protected]>
4*6a54128fSAndroid Build Coastguard Worker (C) 2002 David Woodhouse <[email protected]>
5*6a54128fSAndroid Build Coastguard Worker
6*6a54128fSAndroid Build Coastguard Worker This program is free software; you can redistribute it and/or modify
7*6a54128fSAndroid Build Coastguard Worker it under the terms of the GNU General Public License as published by
8*6a54128fSAndroid Build Coastguard Worker the Free Software Foundation; either version 2 of the License, or
9*6a54128fSAndroid Build Coastguard Worker (at your option) any later version.
10*6a54128fSAndroid Build Coastguard Worker
11*6a54128fSAndroid Build Coastguard Worker This program is distributed in the hope that it will be useful,
12*6a54128fSAndroid Build Coastguard Worker but WITHOUT ANY WARRANTY; without even the implied warranty of
13*6a54128fSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*6a54128fSAndroid Build Coastguard Worker GNU General Public License for more details.
15*6a54128fSAndroid Build Coastguard Worker
16*6a54128fSAndroid Build Coastguard Worker You should have received a copy of the GNU General Public License
17*6a54128fSAndroid Build Coastguard Worker along with this program; if not, write to the Free Software
18*6a54128fSAndroid Build Coastguard Worker Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*6a54128fSAndroid Build Coastguard Worker
20*6a54128fSAndroid Build Coastguard Worker linux/lib/rbtree.c
21*6a54128fSAndroid Build Coastguard Worker */
22*6a54128fSAndroid Build Coastguard Worker
23*6a54128fSAndroid Build Coastguard Worker #include "rbtree.h"
24*6a54128fSAndroid Build Coastguard Worker
__rb_rotate_left(struct rb_node * node,struct rb_root * root)25*6a54128fSAndroid Build Coastguard Worker static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
26*6a54128fSAndroid Build Coastguard Worker {
27*6a54128fSAndroid Build Coastguard Worker struct rb_node *right = node->rb_right;
28*6a54128fSAndroid Build Coastguard Worker struct rb_node *parent = ext2fs_rb_parent(node);
29*6a54128fSAndroid Build Coastguard Worker
30*6a54128fSAndroid Build Coastguard Worker if ((node->rb_right = right->rb_left))
31*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(right->rb_left, node);
32*6a54128fSAndroid Build Coastguard Worker right->rb_left = node;
33*6a54128fSAndroid Build Coastguard Worker
34*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(right, parent);
35*6a54128fSAndroid Build Coastguard Worker
36*6a54128fSAndroid Build Coastguard Worker if (parent)
37*6a54128fSAndroid Build Coastguard Worker {
38*6a54128fSAndroid Build Coastguard Worker if (node == parent->rb_left)
39*6a54128fSAndroid Build Coastguard Worker parent->rb_left = right;
40*6a54128fSAndroid Build Coastguard Worker else
41*6a54128fSAndroid Build Coastguard Worker parent->rb_right = right;
42*6a54128fSAndroid Build Coastguard Worker }
43*6a54128fSAndroid Build Coastguard Worker else
44*6a54128fSAndroid Build Coastguard Worker root->rb_node = right;
45*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(node, right);
46*6a54128fSAndroid Build Coastguard Worker }
47*6a54128fSAndroid Build Coastguard Worker
__rb_rotate_right(struct rb_node * node,struct rb_root * root)48*6a54128fSAndroid Build Coastguard Worker static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
49*6a54128fSAndroid Build Coastguard Worker {
50*6a54128fSAndroid Build Coastguard Worker struct rb_node *left = node->rb_left;
51*6a54128fSAndroid Build Coastguard Worker struct rb_node *parent = ext2fs_rb_parent(node);
52*6a54128fSAndroid Build Coastguard Worker
53*6a54128fSAndroid Build Coastguard Worker if ((node->rb_left = left->rb_right))
54*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(left->rb_right, node);
55*6a54128fSAndroid Build Coastguard Worker left->rb_right = node;
56*6a54128fSAndroid Build Coastguard Worker
57*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(left, parent);
58*6a54128fSAndroid Build Coastguard Worker
59*6a54128fSAndroid Build Coastguard Worker if (parent)
60*6a54128fSAndroid Build Coastguard Worker {
61*6a54128fSAndroid Build Coastguard Worker if (node == parent->rb_right)
62*6a54128fSAndroid Build Coastguard Worker parent->rb_right = left;
63*6a54128fSAndroid Build Coastguard Worker else
64*6a54128fSAndroid Build Coastguard Worker parent->rb_left = left;
65*6a54128fSAndroid Build Coastguard Worker }
66*6a54128fSAndroid Build Coastguard Worker else
67*6a54128fSAndroid Build Coastguard Worker root->rb_node = left;
68*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(node, left);
69*6a54128fSAndroid Build Coastguard Worker }
70*6a54128fSAndroid Build Coastguard Worker
ext2fs_rb_insert_color(struct rb_node * node,struct rb_root * root)71*6a54128fSAndroid Build Coastguard Worker void ext2fs_rb_insert_color(struct rb_node *node, struct rb_root *root)
72*6a54128fSAndroid Build Coastguard Worker {
73*6a54128fSAndroid Build Coastguard Worker struct rb_node *parent, *gparent;
74*6a54128fSAndroid Build Coastguard Worker
75*6a54128fSAndroid Build Coastguard Worker while ((parent = ext2fs_rb_parent(node)) && ext2fs_rb_is_red(parent))
76*6a54128fSAndroid Build Coastguard Worker {
77*6a54128fSAndroid Build Coastguard Worker gparent = ext2fs_rb_parent(parent);
78*6a54128fSAndroid Build Coastguard Worker
79*6a54128fSAndroid Build Coastguard Worker if (parent == gparent->rb_left)
80*6a54128fSAndroid Build Coastguard Worker {
81*6a54128fSAndroid Build Coastguard Worker {
82*6a54128fSAndroid Build Coastguard Worker register struct rb_node *uncle = gparent->rb_right;
83*6a54128fSAndroid Build Coastguard Worker if (uncle && ext2fs_rb_is_red(uncle))
84*6a54128fSAndroid Build Coastguard Worker {
85*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(uncle);
86*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(parent);
87*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(gparent);
88*6a54128fSAndroid Build Coastguard Worker node = gparent;
89*6a54128fSAndroid Build Coastguard Worker continue;
90*6a54128fSAndroid Build Coastguard Worker }
91*6a54128fSAndroid Build Coastguard Worker }
92*6a54128fSAndroid Build Coastguard Worker
93*6a54128fSAndroid Build Coastguard Worker if (parent->rb_right == node)
94*6a54128fSAndroid Build Coastguard Worker {
95*6a54128fSAndroid Build Coastguard Worker register struct rb_node *tmp;
96*6a54128fSAndroid Build Coastguard Worker __rb_rotate_left(parent, root);
97*6a54128fSAndroid Build Coastguard Worker tmp = parent;
98*6a54128fSAndroid Build Coastguard Worker parent = node;
99*6a54128fSAndroid Build Coastguard Worker node = tmp;
100*6a54128fSAndroid Build Coastguard Worker }
101*6a54128fSAndroid Build Coastguard Worker
102*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(parent);
103*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(gparent);
104*6a54128fSAndroid Build Coastguard Worker __rb_rotate_right(gparent, root);
105*6a54128fSAndroid Build Coastguard Worker } else {
106*6a54128fSAndroid Build Coastguard Worker {
107*6a54128fSAndroid Build Coastguard Worker register struct rb_node *uncle = gparent->rb_left;
108*6a54128fSAndroid Build Coastguard Worker if (uncle && ext2fs_rb_is_red(uncle))
109*6a54128fSAndroid Build Coastguard Worker {
110*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(uncle);
111*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(parent);
112*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(gparent);
113*6a54128fSAndroid Build Coastguard Worker node = gparent;
114*6a54128fSAndroid Build Coastguard Worker continue;
115*6a54128fSAndroid Build Coastguard Worker }
116*6a54128fSAndroid Build Coastguard Worker }
117*6a54128fSAndroid Build Coastguard Worker
118*6a54128fSAndroid Build Coastguard Worker if (parent->rb_left == node)
119*6a54128fSAndroid Build Coastguard Worker {
120*6a54128fSAndroid Build Coastguard Worker register struct rb_node *tmp;
121*6a54128fSAndroid Build Coastguard Worker __rb_rotate_right(parent, root);
122*6a54128fSAndroid Build Coastguard Worker tmp = parent;
123*6a54128fSAndroid Build Coastguard Worker parent = node;
124*6a54128fSAndroid Build Coastguard Worker node = tmp;
125*6a54128fSAndroid Build Coastguard Worker }
126*6a54128fSAndroid Build Coastguard Worker
127*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(parent);
128*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(gparent);
129*6a54128fSAndroid Build Coastguard Worker __rb_rotate_left(gparent, root);
130*6a54128fSAndroid Build Coastguard Worker }
131*6a54128fSAndroid Build Coastguard Worker }
132*6a54128fSAndroid Build Coastguard Worker
133*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(root->rb_node);
134*6a54128fSAndroid Build Coastguard Worker }
135*6a54128fSAndroid Build Coastguard Worker
__rb_erase_color(struct rb_node * node,struct rb_node * parent,struct rb_root * root)136*6a54128fSAndroid Build Coastguard Worker static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
137*6a54128fSAndroid Build Coastguard Worker struct rb_root *root)
138*6a54128fSAndroid Build Coastguard Worker {
139*6a54128fSAndroid Build Coastguard Worker struct rb_node *other;
140*6a54128fSAndroid Build Coastguard Worker
141*6a54128fSAndroid Build Coastguard Worker while ((!node || ext2fs_rb_is_black(node)) && node != root->rb_node)
142*6a54128fSAndroid Build Coastguard Worker {
143*6a54128fSAndroid Build Coastguard Worker if (parent->rb_left == node)
144*6a54128fSAndroid Build Coastguard Worker {
145*6a54128fSAndroid Build Coastguard Worker other = parent->rb_right;
146*6a54128fSAndroid Build Coastguard Worker if (ext2fs_rb_is_red(other))
147*6a54128fSAndroid Build Coastguard Worker {
148*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(other);
149*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(parent);
150*6a54128fSAndroid Build Coastguard Worker __rb_rotate_left(parent, root);
151*6a54128fSAndroid Build Coastguard Worker other = parent->rb_right;
152*6a54128fSAndroid Build Coastguard Worker }
153*6a54128fSAndroid Build Coastguard Worker if ((!other->rb_left || ext2fs_rb_is_black(other->rb_left)) &&
154*6a54128fSAndroid Build Coastguard Worker (!other->rb_right || ext2fs_rb_is_black(other->rb_right)))
155*6a54128fSAndroid Build Coastguard Worker {
156*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(other);
157*6a54128fSAndroid Build Coastguard Worker node = parent;
158*6a54128fSAndroid Build Coastguard Worker parent = ext2fs_rb_parent(node);
159*6a54128fSAndroid Build Coastguard Worker }
160*6a54128fSAndroid Build Coastguard Worker else
161*6a54128fSAndroid Build Coastguard Worker {
162*6a54128fSAndroid Build Coastguard Worker if (!other->rb_right || ext2fs_rb_is_black(other->rb_right))
163*6a54128fSAndroid Build Coastguard Worker {
164*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(other->rb_left);
165*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(other);
166*6a54128fSAndroid Build Coastguard Worker __rb_rotate_right(other, root);
167*6a54128fSAndroid Build Coastguard Worker other = parent->rb_right;
168*6a54128fSAndroid Build Coastguard Worker }
169*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_color(other, ext2fs_rb_color(parent));
170*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(parent);
171*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(other->rb_right);
172*6a54128fSAndroid Build Coastguard Worker __rb_rotate_left(parent, root);
173*6a54128fSAndroid Build Coastguard Worker node = root->rb_node;
174*6a54128fSAndroid Build Coastguard Worker break;
175*6a54128fSAndroid Build Coastguard Worker }
176*6a54128fSAndroid Build Coastguard Worker }
177*6a54128fSAndroid Build Coastguard Worker else
178*6a54128fSAndroid Build Coastguard Worker {
179*6a54128fSAndroid Build Coastguard Worker other = parent->rb_left;
180*6a54128fSAndroid Build Coastguard Worker if (ext2fs_rb_is_red(other))
181*6a54128fSAndroid Build Coastguard Worker {
182*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(other);
183*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(parent);
184*6a54128fSAndroid Build Coastguard Worker __rb_rotate_right(parent, root);
185*6a54128fSAndroid Build Coastguard Worker other = parent->rb_left;
186*6a54128fSAndroid Build Coastguard Worker }
187*6a54128fSAndroid Build Coastguard Worker if ((!other->rb_left || ext2fs_rb_is_black(other->rb_left)) &&
188*6a54128fSAndroid Build Coastguard Worker (!other->rb_right || ext2fs_rb_is_black(other->rb_right)))
189*6a54128fSAndroid Build Coastguard Worker {
190*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(other);
191*6a54128fSAndroid Build Coastguard Worker node = parent;
192*6a54128fSAndroid Build Coastguard Worker parent = ext2fs_rb_parent(node);
193*6a54128fSAndroid Build Coastguard Worker }
194*6a54128fSAndroid Build Coastguard Worker else
195*6a54128fSAndroid Build Coastguard Worker {
196*6a54128fSAndroid Build Coastguard Worker if (!other->rb_left || ext2fs_rb_is_black(other->rb_left))
197*6a54128fSAndroid Build Coastguard Worker {
198*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(other->rb_right);
199*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_red(other);
200*6a54128fSAndroid Build Coastguard Worker __rb_rotate_left(other, root);
201*6a54128fSAndroid Build Coastguard Worker other = parent->rb_left;
202*6a54128fSAndroid Build Coastguard Worker }
203*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_color(other, ext2fs_rb_color(parent));
204*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(parent);
205*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(other->rb_left);
206*6a54128fSAndroid Build Coastguard Worker __rb_rotate_right(parent, root);
207*6a54128fSAndroid Build Coastguard Worker node = root->rb_node;
208*6a54128fSAndroid Build Coastguard Worker break;
209*6a54128fSAndroid Build Coastguard Worker }
210*6a54128fSAndroid Build Coastguard Worker }
211*6a54128fSAndroid Build Coastguard Worker }
212*6a54128fSAndroid Build Coastguard Worker if (node)
213*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_black(node);
214*6a54128fSAndroid Build Coastguard Worker }
215*6a54128fSAndroid Build Coastguard Worker
ext2fs_rb_erase(struct rb_node * node,struct rb_root * root)216*6a54128fSAndroid Build Coastguard Worker void ext2fs_rb_erase(struct rb_node *node, struct rb_root *root)
217*6a54128fSAndroid Build Coastguard Worker {
218*6a54128fSAndroid Build Coastguard Worker struct rb_node *child, *parent;
219*6a54128fSAndroid Build Coastguard Worker int color;
220*6a54128fSAndroid Build Coastguard Worker
221*6a54128fSAndroid Build Coastguard Worker if (!node->rb_left)
222*6a54128fSAndroid Build Coastguard Worker child = node->rb_right;
223*6a54128fSAndroid Build Coastguard Worker else if (!node->rb_right)
224*6a54128fSAndroid Build Coastguard Worker child = node->rb_left;
225*6a54128fSAndroid Build Coastguard Worker else
226*6a54128fSAndroid Build Coastguard Worker {
227*6a54128fSAndroid Build Coastguard Worker struct rb_node *old = node, *left;
228*6a54128fSAndroid Build Coastguard Worker
229*6a54128fSAndroid Build Coastguard Worker node = node->rb_right;
230*6a54128fSAndroid Build Coastguard Worker while ((left = node->rb_left) != NULL)
231*6a54128fSAndroid Build Coastguard Worker node = left;
232*6a54128fSAndroid Build Coastguard Worker
233*6a54128fSAndroid Build Coastguard Worker if (ext2fs_rb_parent(old)) {
234*6a54128fSAndroid Build Coastguard Worker if (ext2fs_rb_parent(old)->rb_left == old)
235*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_parent(old)->rb_left = node;
236*6a54128fSAndroid Build Coastguard Worker else
237*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_parent(old)->rb_right = node;
238*6a54128fSAndroid Build Coastguard Worker } else
239*6a54128fSAndroid Build Coastguard Worker root->rb_node = node;
240*6a54128fSAndroid Build Coastguard Worker
241*6a54128fSAndroid Build Coastguard Worker child = node->rb_right;
242*6a54128fSAndroid Build Coastguard Worker parent = ext2fs_rb_parent(node);
243*6a54128fSAndroid Build Coastguard Worker color = ext2fs_rb_color(node);
244*6a54128fSAndroid Build Coastguard Worker
245*6a54128fSAndroid Build Coastguard Worker if (parent == old) {
246*6a54128fSAndroid Build Coastguard Worker parent = node;
247*6a54128fSAndroid Build Coastguard Worker } else {
248*6a54128fSAndroid Build Coastguard Worker if (child)
249*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(child, parent);
250*6a54128fSAndroid Build Coastguard Worker parent->rb_left = child;
251*6a54128fSAndroid Build Coastguard Worker
252*6a54128fSAndroid Build Coastguard Worker node->rb_right = old->rb_right;
253*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(old->rb_right, node);
254*6a54128fSAndroid Build Coastguard Worker }
255*6a54128fSAndroid Build Coastguard Worker
256*6a54128fSAndroid Build Coastguard Worker node->rb_parent_color = old->rb_parent_color;
257*6a54128fSAndroid Build Coastguard Worker node->rb_left = old->rb_left;
258*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(old->rb_left, node);
259*6a54128fSAndroid Build Coastguard Worker
260*6a54128fSAndroid Build Coastguard Worker goto color;
261*6a54128fSAndroid Build Coastguard Worker }
262*6a54128fSAndroid Build Coastguard Worker
263*6a54128fSAndroid Build Coastguard Worker parent = ext2fs_rb_parent(node);
264*6a54128fSAndroid Build Coastguard Worker color = ext2fs_rb_color(node);
265*6a54128fSAndroid Build Coastguard Worker
266*6a54128fSAndroid Build Coastguard Worker if (child)
267*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(child, parent);
268*6a54128fSAndroid Build Coastguard Worker if (parent)
269*6a54128fSAndroid Build Coastguard Worker {
270*6a54128fSAndroid Build Coastguard Worker if (parent->rb_left == node)
271*6a54128fSAndroid Build Coastguard Worker parent->rb_left = child;
272*6a54128fSAndroid Build Coastguard Worker else
273*6a54128fSAndroid Build Coastguard Worker parent->rb_right = child;
274*6a54128fSAndroid Build Coastguard Worker }
275*6a54128fSAndroid Build Coastguard Worker else
276*6a54128fSAndroid Build Coastguard Worker root->rb_node = child;
277*6a54128fSAndroid Build Coastguard Worker
278*6a54128fSAndroid Build Coastguard Worker color:
279*6a54128fSAndroid Build Coastguard Worker if (color == RB_BLACK)
280*6a54128fSAndroid Build Coastguard Worker __rb_erase_color(child, parent, root);
281*6a54128fSAndroid Build Coastguard Worker }
282*6a54128fSAndroid Build Coastguard Worker
283*6a54128fSAndroid Build Coastguard Worker /*
284*6a54128fSAndroid Build Coastguard Worker * This function returns the first node (in sort order) of the tree.
285*6a54128fSAndroid Build Coastguard Worker */
ext2fs_rb_first(const struct rb_root * root)286*6a54128fSAndroid Build Coastguard Worker struct rb_node *ext2fs_rb_first(const struct rb_root *root)
287*6a54128fSAndroid Build Coastguard Worker {
288*6a54128fSAndroid Build Coastguard Worker struct rb_node *n;
289*6a54128fSAndroid Build Coastguard Worker
290*6a54128fSAndroid Build Coastguard Worker n = root->rb_node;
291*6a54128fSAndroid Build Coastguard Worker if (!n)
292*6a54128fSAndroid Build Coastguard Worker return NULL;
293*6a54128fSAndroid Build Coastguard Worker while (n->rb_left)
294*6a54128fSAndroid Build Coastguard Worker n = n->rb_left;
295*6a54128fSAndroid Build Coastguard Worker return n;
296*6a54128fSAndroid Build Coastguard Worker }
297*6a54128fSAndroid Build Coastguard Worker
ext2fs_rb_last(const struct rb_root * root)298*6a54128fSAndroid Build Coastguard Worker struct rb_node *ext2fs_rb_last(const struct rb_root *root)
299*6a54128fSAndroid Build Coastguard Worker {
300*6a54128fSAndroid Build Coastguard Worker struct rb_node *n;
301*6a54128fSAndroid Build Coastguard Worker
302*6a54128fSAndroid Build Coastguard Worker n = root->rb_node;
303*6a54128fSAndroid Build Coastguard Worker if (!n)
304*6a54128fSAndroid Build Coastguard Worker return NULL;
305*6a54128fSAndroid Build Coastguard Worker while (n->rb_right)
306*6a54128fSAndroid Build Coastguard Worker n = n->rb_right;
307*6a54128fSAndroid Build Coastguard Worker return n;
308*6a54128fSAndroid Build Coastguard Worker }
309*6a54128fSAndroid Build Coastguard Worker
ext2fs_rb_next(struct rb_node * node)310*6a54128fSAndroid Build Coastguard Worker struct rb_node *ext2fs_rb_next(struct rb_node *node)
311*6a54128fSAndroid Build Coastguard Worker {
312*6a54128fSAndroid Build Coastguard Worker struct rb_node *parent;
313*6a54128fSAndroid Build Coastguard Worker
314*6a54128fSAndroid Build Coastguard Worker if (ext2fs_rb_parent(node) == node)
315*6a54128fSAndroid Build Coastguard Worker return NULL;
316*6a54128fSAndroid Build Coastguard Worker
317*6a54128fSAndroid Build Coastguard Worker /* If we have a right-hand child, go down and then left as far
318*6a54128fSAndroid Build Coastguard Worker as we can. */
319*6a54128fSAndroid Build Coastguard Worker if (node->rb_right) {
320*6a54128fSAndroid Build Coastguard Worker node = node->rb_right;
321*6a54128fSAndroid Build Coastguard Worker while (node->rb_left)
322*6a54128fSAndroid Build Coastguard Worker node=node->rb_left;
323*6a54128fSAndroid Build Coastguard Worker return (struct rb_node *)node;
324*6a54128fSAndroid Build Coastguard Worker }
325*6a54128fSAndroid Build Coastguard Worker
326*6a54128fSAndroid Build Coastguard Worker /* No right-hand children. Everything down and left is
327*6a54128fSAndroid Build Coastguard Worker smaller than us, so any 'next' node must be in the general
328*6a54128fSAndroid Build Coastguard Worker direction of our parent. Go up the tree; any time the
329*6a54128fSAndroid Build Coastguard Worker ancestor is a right-hand child of its parent, keep going
330*6a54128fSAndroid Build Coastguard Worker up. First time it's a left-hand child of its parent, said
331*6a54128fSAndroid Build Coastguard Worker parent is our 'next' node. */
332*6a54128fSAndroid Build Coastguard Worker while ((parent = ext2fs_rb_parent(node)) && node == parent->rb_right)
333*6a54128fSAndroid Build Coastguard Worker node = parent;
334*6a54128fSAndroid Build Coastguard Worker
335*6a54128fSAndroid Build Coastguard Worker return parent;
336*6a54128fSAndroid Build Coastguard Worker }
337*6a54128fSAndroid Build Coastguard Worker
ext2fs_rb_prev(struct rb_node * node)338*6a54128fSAndroid Build Coastguard Worker struct rb_node *ext2fs_rb_prev(struct rb_node *node)
339*6a54128fSAndroid Build Coastguard Worker {
340*6a54128fSAndroid Build Coastguard Worker struct rb_node *parent;
341*6a54128fSAndroid Build Coastguard Worker
342*6a54128fSAndroid Build Coastguard Worker if (ext2fs_rb_parent(node) == node)
343*6a54128fSAndroid Build Coastguard Worker return NULL;
344*6a54128fSAndroid Build Coastguard Worker
345*6a54128fSAndroid Build Coastguard Worker /* If we have a left-hand child, go down and then right as far
346*6a54128fSAndroid Build Coastguard Worker as we can. */
347*6a54128fSAndroid Build Coastguard Worker if (node->rb_left) {
348*6a54128fSAndroid Build Coastguard Worker node = node->rb_left;
349*6a54128fSAndroid Build Coastguard Worker while (node->rb_right)
350*6a54128fSAndroid Build Coastguard Worker node=node->rb_right;
351*6a54128fSAndroid Build Coastguard Worker return (struct rb_node *)node;
352*6a54128fSAndroid Build Coastguard Worker }
353*6a54128fSAndroid Build Coastguard Worker
354*6a54128fSAndroid Build Coastguard Worker /* No left-hand children. Go up till we find an ancestor which
355*6a54128fSAndroid Build Coastguard Worker is a right-hand child of its parent */
356*6a54128fSAndroid Build Coastguard Worker while ((parent = ext2fs_rb_parent(node)) && node == parent->rb_left)
357*6a54128fSAndroid Build Coastguard Worker node = parent;
358*6a54128fSAndroid Build Coastguard Worker
359*6a54128fSAndroid Build Coastguard Worker return parent;
360*6a54128fSAndroid Build Coastguard Worker }
361*6a54128fSAndroid Build Coastguard Worker
ext2fs_rb_replace_node(struct rb_node * victim,struct rb_node * new,struct rb_root * root)362*6a54128fSAndroid Build Coastguard Worker void ext2fs_rb_replace_node(struct rb_node *victim, struct rb_node *new,
363*6a54128fSAndroid Build Coastguard Worker struct rb_root *root)
364*6a54128fSAndroid Build Coastguard Worker {
365*6a54128fSAndroid Build Coastguard Worker struct rb_node *parent = ext2fs_rb_parent(victim);
366*6a54128fSAndroid Build Coastguard Worker
367*6a54128fSAndroid Build Coastguard Worker /* Set the surrounding nodes to point to the replacement */
368*6a54128fSAndroid Build Coastguard Worker if (parent) {
369*6a54128fSAndroid Build Coastguard Worker if (victim == parent->rb_left)
370*6a54128fSAndroid Build Coastguard Worker parent->rb_left = new;
371*6a54128fSAndroid Build Coastguard Worker else
372*6a54128fSAndroid Build Coastguard Worker parent->rb_right = new;
373*6a54128fSAndroid Build Coastguard Worker } else {
374*6a54128fSAndroid Build Coastguard Worker root->rb_node = new;
375*6a54128fSAndroid Build Coastguard Worker }
376*6a54128fSAndroid Build Coastguard Worker if (victim->rb_left)
377*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(victim->rb_left, new);
378*6a54128fSAndroid Build Coastguard Worker if (victim->rb_right)
379*6a54128fSAndroid Build Coastguard Worker ext2fs_rb_set_parent(victim->rb_right, new);
380*6a54128fSAndroid Build Coastguard Worker
381*6a54128fSAndroid Build Coastguard Worker /* Copy the pointers/colour from the victim to the replacement */
382*6a54128fSAndroid Build Coastguard Worker *new = *victim;
383*6a54128fSAndroid Build Coastguard Worker }
384