s3: smbd: Move check_fsp_open() and check_fsp() to smb1_reply.c
[Samba.git] / lib / util / rbtree.c
blobaa663f49f028faa0ff5e63c0cb549aa628b96098
1 /*
2 Red Black Trees
3 (C) 1999 Andrea Arcangeli <andrea@suse.de>
4 (C) 2002 David Woodhouse <dwmw2@infradead.org>
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.
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.
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
20 linux/lib/rbtree.c
23 #include "replace.h"
24 #include "rbtree.h"
25 #include "fault.h"
27 #define RB_RED 0
28 #define RB_BLACK 1
30 #define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
31 #define rb_color(r) ((r)->rb_parent_color & 1)
32 #define rb_is_red(r) (!rb_color(r))
33 #define rb_is_black(r) rb_color(r)
34 #define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
35 #define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
37 static void rb_set_parent(struct rb_node *rb, struct rb_node *p)
39 rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
41 static void rb_set_color(struct rb_node *rb, int color)
43 rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
46 #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
47 #define RB_EMPTY_NODE(node) (rb_parent(node) == node)
48 #define RB_CLEAR_NODE(node) (rb_set_parent(node, node))
50 static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
52 struct rb_node *right = node->rb_right;
53 struct rb_node *parent = rb_parent(node);
55 if ((node->rb_right = right->rb_left))
56 rb_set_parent(right->rb_left, node);
57 right->rb_left = node;
59 rb_set_parent(right, parent);
61 if (parent)
63 if (node == parent->rb_left)
64 parent->rb_left = right;
65 else
66 parent->rb_right = right;
68 else
69 root->rb_node = right;
70 rb_set_parent(node, right);
73 static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
75 struct rb_node *left = node->rb_left;
76 struct rb_node *parent = rb_parent(node);
78 if ((node->rb_left = left->rb_right))
79 rb_set_parent(left->rb_right, node);
80 left->rb_right = node;
82 rb_set_parent(left, parent);
84 if (parent)
86 if (node == parent->rb_right)
87 parent->rb_right = left;
88 else
89 parent->rb_left = left;
91 else
92 root->rb_node = left;
93 rb_set_parent(node, left);
96 void rb_insert_color(struct rb_node *node, struct rb_root *root)
98 struct rb_node *parent, *gparent;
100 while ((parent = rb_parent(node)) && rb_is_red(parent))
102 gparent = rb_parent(parent);
104 if (parent == gparent->rb_left)
107 register struct rb_node *uncle = gparent->rb_right;
108 if (uncle && rb_is_red(uncle))
110 rb_set_black(uncle);
111 rb_set_black(parent);
112 rb_set_red(gparent);
113 node = gparent;
114 continue;
118 if (parent->rb_right == node)
120 register struct rb_node *tmp;
121 __rb_rotate_left(parent, root);
122 tmp = parent;
123 parent = node;
124 node = tmp;
127 rb_set_black(parent);
128 rb_set_red(gparent);
129 __rb_rotate_right(gparent, root);
130 } else {
132 register struct rb_node *uncle = gparent->rb_left;
133 if (uncle && rb_is_red(uncle))
135 rb_set_black(uncle);
136 rb_set_black(parent);
137 rb_set_red(gparent);
138 node = gparent;
139 continue;
143 if (parent->rb_left == node)
145 register struct rb_node *tmp;
146 __rb_rotate_right(parent, root);
147 tmp = parent;
148 parent = node;
149 node = tmp;
152 rb_set_black(parent);
153 rb_set_red(gparent);
154 __rb_rotate_left(gparent, root);
158 rb_set_black(root->rb_node);
161 static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
162 struct rb_root *root)
164 struct rb_node *other;
166 while ((!node || rb_is_black(node)) && node != root->rb_node)
168 if (parent->rb_left == node)
170 other = parent->rb_right;
171 if (other == NULL) {
172 /* we should never get here */
173 smb_panic("corrupted rb tree");
174 /* satisfy static checkers */
175 return;
177 if (rb_is_red(other))
179 rb_set_black(other);
180 rb_set_red(parent);
181 __rb_rotate_left(parent, root);
182 other = parent->rb_right;
184 if ((!other->rb_left || rb_is_black(other->rb_left)) &&
185 (!other->rb_right || rb_is_black(other->rb_right)))
187 rb_set_red(other);
188 node = parent;
189 parent = rb_parent(node);
191 else
193 if (!other->rb_right || rb_is_black(other->rb_right))
195 struct rb_node *o_left;
196 if ((o_left = other->rb_left))
197 rb_set_black(o_left);
198 rb_set_red(other);
199 __rb_rotate_right(other, root);
200 other = parent->rb_right;
202 rb_set_color(other, rb_color(parent));
203 rb_set_black(parent);
204 if (other->rb_right)
205 rb_set_black(other->rb_right);
206 __rb_rotate_left(parent, root);
207 node = root->rb_node;
208 break;
211 else
213 other = parent->rb_left;
214 if (rb_is_red(other))
216 rb_set_black(other);
217 rb_set_red(parent);
218 __rb_rotate_right(parent, root);
219 other = parent->rb_left;
221 if ((!other->rb_left || rb_is_black(other->rb_left)) &&
222 (!other->rb_right || rb_is_black(other->rb_right)))
224 rb_set_red(other);
225 node = parent;
226 parent = rb_parent(node);
228 else
230 if (!other->rb_left || rb_is_black(other->rb_left))
232 register struct rb_node *o_right;
233 if ((o_right = other->rb_right))
234 rb_set_black(o_right);
235 rb_set_red(other);
236 __rb_rotate_left(other, root);
237 other = parent->rb_left;
239 rb_set_color(other, rb_color(parent));
240 rb_set_black(parent);
241 if (other->rb_left)
242 rb_set_black(other->rb_left);
243 __rb_rotate_right(parent, root);
244 node = root->rb_node;
245 break;
249 if (node)
250 rb_set_black(node);
253 void rb_erase(struct rb_node *node, struct rb_root *root)
255 struct rb_node *child, *parent;
256 int color;
258 if (!node->rb_left)
259 child = node->rb_right;
260 else if (!node->rb_right)
261 child = node->rb_left;
262 else
264 struct rb_node *old = node, *left;
266 node = node->rb_right;
267 while ((left = node->rb_left) != NULL)
268 node = left;
269 child = node->rb_right;
270 parent = rb_parent(node);
271 color = rb_color(node);
273 if (child)
274 rb_set_parent(child, parent);
275 if (parent == old) {
276 parent->rb_right = child;
277 parent = node;
278 } else
279 parent->rb_left = child;
281 node->rb_parent_color = old->rb_parent_color;
282 node->rb_right = old->rb_right;
283 node->rb_left = old->rb_left;
285 if (rb_parent(old))
287 if (rb_parent(old)->rb_left == old)
288 rb_parent(old)->rb_left = node;
289 else
290 rb_parent(old)->rb_right = node;
291 } else
292 root->rb_node = node;
294 rb_set_parent(old->rb_left, node);
295 if (old->rb_right)
296 rb_set_parent(old->rb_right, node);
297 goto color;
300 parent = rb_parent(node);
301 color = rb_color(node);
303 if (child)
304 rb_set_parent(child, parent);
305 if (parent)
307 if (parent->rb_left == node)
308 parent->rb_left = child;
309 else
310 parent->rb_right = child;
312 else
313 root->rb_node = child;
315 color:
316 if (color == RB_BLACK)
317 __rb_erase_color(child, parent, root);
321 * This function returns the first node (in sort order) of the tree.
323 struct rb_node *rb_first(struct rb_root *root)
325 struct rb_node *n;
327 n = root->rb_node;
328 if (!n)
329 return NULL;
330 while (n->rb_left)
331 n = n->rb_left;
332 return n;
335 struct rb_node *rb_last(struct rb_root *root)
337 struct rb_node *n;
339 n = root->rb_node;
340 if (!n)
341 return NULL;
342 while (n->rb_right)
343 n = n->rb_right;
344 return n;
347 struct rb_node *rb_next(struct rb_node *node)
349 struct rb_node *parent;
351 if (rb_parent(node) == node)
352 return NULL;
354 /* If we have a right-hand child, go down and then left as far
355 as we can. */
356 if (node->rb_right) {
357 node = node->rb_right;
358 while (node->rb_left)
359 node=node->rb_left;
360 return node;
363 /* No right-hand children. Everything down and left is
364 smaller than us, so any 'next' node must be in the general
365 direction of our parent. Go up the tree; any time the
366 ancestor is a right-hand child of its parent, keep going
367 up. First time it's a left-hand child of its parent, said
368 parent is our 'next' node. */
369 while ((parent = rb_parent(node)) && node == parent->rb_right)
370 node = parent;
372 return parent;
375 struct rb_node *rb_prev(struct rb_node *node)
377 struct rb_node *parent;
379 if (rb_parent(node) == node)
380 return NULL;
382 /* If we have a left-hand child, go down and then right as far
383 as we can. */
384 if (node->rb_left) {
385 node = node->rb_left;
386 while (node->rb_right)
387 node=node->rb_right;
388 return node;
391 /* No left-hand children. Go up till we find an ancestor which
392 is a right-hand child of its parent */
393 while ((parent = rb_parent(node)) && node == parent->rb_left)
394 node = parent;
396 return parent;
399 void rb_replace_node(struct rb_node *victim, struct rb_node *new_node,
400 struct rb_root *root)
402 struct rb_node *parent = rb_parent(victim);
404 /* Set the surrounding nodes to point to the replacement */
405 if (parent) {
406 if (victim == parent->rb_left)
407 parent->rb_left = new_node;
408 else
409 parent->rb_right = new_node;
410 } else {
411 root->rb_node = new_node;
413 if (victim->rb_left)
414 rb_set_parent(victim->rb_left, new_node);
415 if (victim->rb_right)
416 rb_set_parent(victim->rb_right, new_node);
418 /* Copy the pointers/colour from the victim to the replacement */
419 *new_node = *victim;
422 void rb_link_node(struct rb_node * node, struct rb_node * parent,
423 struct rb_node ** rb_link)
425 node->rb_parent_color = (unsigned long )parent;
426 node->rb_left = node->rb_right = NULL;
428 *rb_link = node;