blob: 11ca6e00f2f71358d44ea832d4adf38637c1cdbb [file] [log] [blame]
Willy Tarreaube384c62007-04-28 14:00:17 +02001/*
2 * tree.h : tree manipulation macros and structures.
3 * (C) 2002 - Willy Tarreau - willy@ant-computing.com
4 *
Willy Tarreauc6ca1a02007-05-13 19:43:47 +02005 * 2007/05/13: adapted to mempools v2.
6 *
Willy Tarreaube384c62007-04-28 14:00:17 +02007 */
8
9#ifndef __TREE_H__
10#define __TREE_H__
11
12#include <import/bitops.h>
13#include <common/memory.h>
14
15/* binary tree node : either 32 bits unsigned long int values, or
16 * 64 bits in two 32 bits unsigned long int values
17 */
18struct ultree {
19 unsigned long low; /* 32 bits low value of this node */
20 unsigned long high; /* 32 bits high value of this node, not used in 32 bits */
21 int level; /* bit level of this node */
22 void *data; /* carried data */
23 struct ultree *left, *right; /* children : left and right. NULL = leaf */
24 struct ultree *up; /* parent node. NULL = root */
25};
26
27/* binary tree node : 64 bits unsigned long long values */
28struct ulltree {
29 unsigned long long value; /* 64 bits value of this node */
30 int level; /* bit level of this node */
31 void *data; /* carried data */
32 struct ulltree *left, *right; /* children : left and right. NULL = leaf */
33 struct ulltree *up; /* parent node. NULL = root */
34};
35
36/* binary tree node : 64 bits in either one ull or two 32 bits unsigned long int values. This
37 * is the common type for all the above trees, which should be cast into it. This makes
38 * pool_free() far simpler since all types share a same pool.
39 */
40struct tree64 {
41 union {
42 struct {
43 unsigned long low; /* 32 bits low value of this node */
44 unsigned long high; /* 32 bits high value of this node */
45 } ul;
46 struct {
47 unsigned long long value; /* 64 bits value of this node */
48 } ull;
49 } value;
50 int level; /* bit level of this node */
51 void *data; /* carried data */
52 struct tree64 *left, *right; /* children : left and right. NULL = leaf */
53 struct tree64 *up; /* parent node. NULL = root */
54};
55
Willy Tarreauc6ca1a02007-05-13 19:43:47 +020056extern struct pool_head *pool2_tree64;
Willy Tarreaube384c62007-04-28 14:00:17 +020057
Willy Tarreaube384c62007-04-28 14:00:17 +020058#define ULTREE_HEAD(l) struct ultree (l) = { .left=NULL, .right=NULL, .up=NULL, .low=0, .level=LONGBITS, .data=NULL }
59#define ULTREE_INIT(l) { (l)->data = (l)->left = (l)->right = NULL; }
60#define ULTREE_INIT_ROOT(l) { (l)->left=(l)->right=(l)->up=(l)->data=NULL; (l)->low=0; (l)->level=LONGBITS; }
61
62#define ULLTREE_HEAD(l) struct ulltree (l) = { .left=NULL, .right=NULL, .up=NULL, .value=0, .level=LLONGBITS, .data=NULL }
63#define ULLTREE_INIT(l) { (l)->data = (l)->left = (l)->right = NULL; }
64#define ULLTREE_INIT_ROOT(l) { (l)->left=(l)->right=(l)->up=(l)->data=NULL; (l)->value=0; (l)->level=LLONGBITS; }
65
66#define UL2TREE_HEAD(l) struct ultree (l) = { .left=NULL, .right=NULL, .up=NULL, .high=0, .low=0, .level=LLONGBITS, .data=NULL }
67#define UL2TREE_INIT(l) { (l)->left = (l)->right = (l)->data = NULL; }
68#define UL2TREE_INIT_ROOT(l) { (l)->left=(l)->right=(l)->up=(l)->data=NULL; (l)->high=(l)->low=0; (l)->level=LLONGBITS; }
69
70/*
71 * inserts necessary nodes to reach <x> in tree starting at <root>. The node
72 * is not created if it exists. It is returned.
73 */
74inline static struct ulltree *__ulltree_insert(struct ulltree *root, unsigned long long x) {
75 int m;
76 struct ulltree *next, *new, *node;
77 struct ulltree **branch;
78 int ffs;
79
80 next = root;
81 ffs = ffs_fast64(x);
82
83 do {
84 root = next;
85
86 if (x == next->value) {
87 return next;
88 }
89
90 if (x & (1ULL << (next->level - 1))) { /* right branch */
91 branch = &next->right;
92 next = *branch;
93 } else {
94 branch = &next->left;
95 next = *branch;
96 }
97
98 if (next == NULL) {
99 /* we'll have to insert our node here */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200100 *branch = new = (struct ulltree *)pool_alloc2(pool2_tree64);
Willy Tarreaube384c62007-04-28 14:00:17 +0200101 ULLTREE_INIT(new);
102 new->up = root;
103 new->value = x;
104 new->level = ffs;
105 return new;
106 }
107
108 /* we'll keep walking down as long as we have all bits in common */
109 } while ((x & ~((1ULL << next->level) - 1)) == next->value);
110
111
112 /* ok, now we know that we must insert between both. */
113
114 /* the new interconnect node */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200115 *branch = node = (struct ulltree *)pool_alloc2(pool2_tree64); /* was <next> */
Willy Tarreaube384c62007-04-28 14:00:17 +0200116 ULLTREE_INIT(node);
117 node->up = root;
118 next->up = node;
119
120 /* we need the common higher bits between x and next->value. */
121
122 /* what differences are there between x and the node here ?
123 * NOTE that m is always < level(parent) because highest bit
124 * of x and next-value are identical here (else they would be
125 * on a different branch).
126 */
127 m = fls_fast64(x ^ next->value) + 1; /* m = lowest identical bit */
128 node->value = x & ~((1ULL << m) - 1); /* value of common bits */
129
130 if (node->value == x) { /* <x> is exactly on this node */
131 /* we must set its real position (eg: 8,10 => m=1 => val=8, m=3)*/
132 node->level = ffs;
133
134 if (next->value & (1ULL << (node->level - 1))) /* right branch */
135 node->right = next;
136 else
137 node->left = next;
138 return node;
139 }
140
141 /* the new leaf now */
142 node->level = m; /* set the level to the lowest common bit */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200143 new = (struct ulltree *)pool_alloc2(pool2_tree64);
Willy Tarreaube384c62007-04-28 14:00:17 +0200144 ULLTREE_INIT(new);
145 new->value = x;
146 new->level = ffs;
147
148 if (x > next->value) {
149 node->left = next;
150 node->right = new;
151 }
152 else {
153 node->left = new;
154 node->right = next;
155 }
156 new->up = node;
157 return new;
158}
159
160/*
161 * inserts necessary nodes to reach <x> in tree starting at <root>. The node
162 * is not created if it exists. It is returned.
163 */
164inline static struct ultree *__ultree_insert(struct ultree *root, unsigned long x) {
165 int m;
166 struct ultree *next, *new, *node;
167 struct ultree **branch;
168 int ffs;
169
170 next = root;
171 ffs = ffs_fast32(x);
172
173 do {
174 root = next;
175
176 if (x == next->low) {
177 return next;
178 }
179
180 if ((x >> (next->level - 1)) & 1) { /* right branch */
181 branch = &next->right;
182 next = *branch;
183 } else {
184 branch = &next->left;
185 next = *branch;
186 }
187
188 if (next == NULL) {
189 /* we'll have to insert our node here */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200190 *branch = new = (struct ultree *)pool_alloc2(pool2_tree64);
Willy Tarreaube384c62007-04-28 14:00:17 +0200191 ULTREE_INIT(new);
192 new->up = root;
193 new->low = x;
194 new->level = ffs;
195 return new;
196 }
197
198 /* we'll keep walking down as long as we have all bits in common */
199 } while ((x & ~((1 << next->level) - 1)) == next->low);
200
201 /* ok, now we know that we must insert between both. */
202
203 /* the new interconnect node */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200204 *branch = node = (struct ultree *)pool_alloc2(pool2_tree64); /* was <next> */
Willy Tarreaube384c62007-04-28 14:00:17 +0200205 ULTREE_INIT(node);
206 node->up = root;
207 next->up = node;
208
209 /* we need the common higher bits between x and next->low. */
210
211 /* what differences are there between x and the node here ?
212 * NOTE that m is always < level(parent) because highest bit
213 * of x and next->low are identical here (else they would be
214 * on a different branch).
215 */
216 m = fls_fast32(x ^ next->low) + 1; /* m = lower identical bit */
217 node->low = x & ~((1 << m) - 1); /* value of common bits */
218
219 if (node->low == x) { /* <x> is exactly on this node */
220 /* we must set its real position (eg: 8,10 => m=1 => val=8, m=3)*/
221 node->level = ffs;
222
223 if (next->low & (1 << (node->level - 1))) /* right branch */
224 node->right = next;
225 else
226 node->left = next;
227 return node;
228 }
229
230 /* the new leaf now */
231 node->level = m; /* set the level to the lowest common bit */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200232 new = (struct ultree *)pool_alloc2(pool2_tree64);
Willy Tarreaube384c62007-04-28 14:00:17 +0200233 ULTREE_INIT(new);
234 new->low = x;
235 new->level = ffs;
236
237 if (x > next->low) {
238 node->left = next;
239 node->right = new;
240 }
241 else {
242 node->left = new;
243 node->right = next;
244 }
245 new->up = node;
246 return new;
247}
248
249
250/*
251 * inserts necessary nodes to reach <h:l> in tree starting at <root>. The node
252 * is not created if it exists. It is returned.
253 */
254inline static struct ultree *__ul2tree_insert(struct ultree *root, unsigned long h, unsigned long l) {
255 int m;
256 struct ultree *next, *new, *node;
257 struct ultree **branch;
258
259 next = root;
260
261 do {
262 root = next;
263
264 if (h == next->high && l == next->low) {
265 return next;
266 }
267
268 branch = &next->left;
269 if (next->level >= 33) {
270 if ((h >> (next->level - 33)) & 1) { /* right branch */
271 branch = &next->right;
Willy Tarreaube384c62007-04-28 14:00:17 +0200272 }
273 }
274 else {
275 if ((l >> (next->level - 1)) & 1) { /* right branch */
276 branch = &next->right;
Willy Tarreaube384c62007-04-28 14:00:17 +0200277 }
278 }
279 next = *branch;
280
Willy Tarreaube384c62007-04-28 14:00:17 +0200281 if (next == NULL) {
282 /* we'll have to insert our node here */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200283 *branch = new =(struct ultree *)pool_alloc2(pool2_tree64);
Willy Tarreaube384c62007-04-28 14:00:17 +0200284 UL2TREE_INIT(new);
285 new->up = root;
286 new->high = h;
287 new->low = l;
288 if (l)
289 new->level = __ffs_fast32(l);
290 else
291 new->level = __ffs_fast32(h) + 32;
292
293 return new;
294 }
295
296 /* we'll keep walking down as long as we have all bits in common */
297 if (next->level >= 32) {
298 if ((h & ~((1 << (next->level-32)) - 1)) != next->high)
299 break;
300 }
301 else {
302 if (h != next->high)
303 break;
304 if ((l & ~((1 << next->level) - 1)) != next->low)
305 break;
306 }
307 } while (1);
308
309 /* ok, now we know that we must insert between both. */
310
311 /* the new interconnect node */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200312 *branch = node = (struct ultree *)pool_alloc2(pool2_tree64); /* was <next> */
Willy Tarreaube384c62007-04-28 14:00:17 +0200313 UL2TREE_INIT(node);
314 node->up = root;
315 next->up = node;
316
317 /* we need the common higher bits between x and next->high:low. */
318
319 /* what differences are there between x and the node here ?
320 * NOTE that m is always < level(parent) because highest bit
321 * of x and next->high:low are identical here (else they would be
322 * on a different branch).
323 */
324 if (h != next->high) {
325 m = fls_fast32(h ^ next->high) + 1; /* m = lower identical bit */
326 node->high = h & ~((1 << m) - 1); /* value of common bits */
327 m += 32;
328 node->low = 0;
329 } else {
330 node->high = h;
331 m = fls_fast32(l ^ next->low) + 1; /* m = lower identical bit */
332 node->low = l & ~((1 << m) - 1); /* value of common bits */
333 }
334
335 if (node->high == h && node->low == l) { /* <h:l> is exactly on this node */
336 /* we must set its real position (eg: 8,10 => m=1 => val=8, m=3)*/
337 if (l) {
338 node->level = ffs_fast32(l);
339 if (next->low & (1 << (node->level - 1))) /* right branch */
340 node->right = next;
341 else
342 node->left = next;
343 }
344 else {
345 node->level = ffs_fast32(h) + 32;
346 if (next->high & (1 << (node->level - 33))) /* right branch */
347 node->right = next;
348 else
349 node->left = next;
350 }
351 return node;
352 }
353
354 /* the new leaf now */
355 node->level = m; /* set the level to the lowest common bit */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200356 new = (struct ultree *)pool_alloc2(pool2_tree64);
Willy Tarreaube384c62007-04-28 14:00:17 +0200357 UL2TREE_INIT(new);
358 new->high = h;
359 new->low = l;
360 if (l)
361 new->level = __ffs_fast32(l);
362 else
363 new->level = __ffs_fast32(h) + 32;
364
365 if (h > next->high || (h == next->high && l > next->low)) {
366 node->left = next;
367 node->right = new;
368 }
369 else {
370 node->left = new;
371 node->right = next;
372 }
373 new->up = node;
374 return new;
375}
376
377
378/*
379 * finds a value in the tree <root>. If it cannot be found, NULL is returned.
380 */
381inline static struct ultree *__ultree_find(struct ultree *root, unsigned long x) {
382 do {
383 if (x == root->low)
384 return root;
385
386 if ((x >> (root->level - 1)) & 1)
387 root = root->right;
388 else
389 root = root->left;
390
391 if (root == NULL)
392 return NULL;
393
394 /* we'll keep walking down as long as we have all bits in common */
395 } while ((x & ~((1 << root->level) - 1)) == root->low);
396
397 /* should be there, but nothing. */
398 return NULL;
399}
400
401/*
402 * finds a value in the tree <root>. If it cannot be found, NULL is returned.
403 */
404inline static struct ulltree *__ulltree_find(struct ulltree *root, unsigned long long x) {
405 do {
406 if (x == root->value)
407 return root;
408
409 if ((x >> (root->level - 1)) & 1)
410 root = root->right;
411 else
412 root = root->left;
413
414 if (root == NULL)
415 return NULL;
416
417 /* we'll keep walking down as long as we have all bits in common */
418 } while ((x & ~((1ULL << root->level) - 1)) == root->value);
419
420 /* should be there, but nothing. */
421 return NULL;
422}
423
424
425/*
426 * walks down the tree <__root> and assigns each of its data to <__data>.
427 * <__stack> is an int array of at least N entries where N is the maximum number
428 * of levels of the tree. <__slen> is an integer variable used as a stack index.
429 * The instruction following the foreach statement is executed for each data,
430 * after the data has been unlinked from the tree.
431 * The nodes are deleted automatically, so it is illegal to manually delete a
432 * node within this loop.
433 */
434#define tree64_foreach_destructive(__root, __data, __stack, __slen) \
435 for (__slen = 0, __stack[0] = __root, __data = NULL; ({ \
436 __label__ __left, __right, __again, __end; \
437 typeof(__root) __ptr = __stack[__slen]; \
438__again: \
439 __data = __ptr->data; \
440 if (__data != NULL) { \
441 __ptr->data = NULL; \
442 goto __end; \
443 } \
444 else if (__ptr->left != NULL) { \
445 __stack[++__slen] = __ptr = __ptr->left; \
446 goto __again; \
447 } \
448 else \
449__left: \
450 if (__ptr->right != NULL) { \
451 __stack[++__slen] = __ptr = __ptr->right; \
452 goto __again; \
453 } \
454 else \
455__right: \
456 if (!__slen--) \
457 goto __end; /* nothing left, don't delete the root node */ \
458 else { \
459 typeof (__root) __old; \
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200460 pool_free2(pool2_tree64, __ptr); \
Willy Tarreaube384c62007-04-28 14:00:17 +0200461 __old = __ptr; \
462 __ptr = __stack[__slen]; \
463 if (__ptr->left == __old) { \
464 /* unlink this node from its parent */ \
465 __ptr->left = NULL; \
466 goto __left; \
467 } \
468 else { \
469 /* no need to unlink, the parent will also die */ \
470 goto __right; \
471 } \
472 } \
473__end: \
474 (__slen >= 0); /* nothing after loop */}); )
475
476
477/*
478 * walks down the tree <__root> of type <__type> and assigns each of its data
479 * to <__data>. <__stack> is an int array of at least N entries where N is the
480 * maximum number of levels of the tree. <__slen> is an integer variable used
481 * as a stack index. The instruction following the foreach statement is
482 * executed for each data, after the data has been unlinked from the tree.
483 */
484#define tree_foreach_destructive(__type, __root, __data, __stack, __slen) \
485 for (__slen = 0, __stack[0] = __root, __data = NULL; ({ \
486 __label__ __left, __right, __again, __end; \
487 typeof(__root) __ptr = __stack[__slen]; \
488__again: \
489 __data = __ptr->data; \
490 if (__data != NULL) { \
491 __ptr->data = NULL; \
492 goto __end; \
493 } \
494 else if (__ptr->left != NULL) { \
495 __stack[++__slen] = __ptr = __ptr->left; \
496 goto __again; \
497 } \
498 else \
499__left: \
500 if (__ptr->right != NULL) { \
501 __stack[++__slen] = __ptr = __ptr->right; \
502 goto __again; \
503 } \
504 else \
505__right: \
506 if (!__slen--) \
507 goto __end; /* nothing left, don't delete the root node */ \
508 else { \
509 typeof (__root) __old; \
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200510 pool_free2(pool##__type, __ptr); \
Willy Tarreaube384c62007-04-28 14:00:17 +0200511 __old = __ptr; \
512 __ptr = __stack[__slen]; \
513 if (__ptr->left == __old) { \
514 /* unlink this node from its parent */ \
515 __ptr->left = NULL; \
516 goto __left; \
517 } \
518 else { \
519 /* no need to unlink, the parent will also die */ \
520 goto __right; \
521 } \
522 } \
523__end: \
524 (__slen >= 0); /* nothing after loop */}); )
525
526
527/*
528 * walks down the tree <__root> and assigns <__data> a pointer to each of its
529 * data pointers. <__stack> is an int array of at least N entries where N is the
530 * maximum number of levels of the tree. <__slen> is an integer variable used as
531 * a stack index. The instruction following the foreach statement is executed
532 * for each data.
533 * The tree will walk down only when the data field is empty (NULL), so it
534 * allows inner breaks, and will restart without losing items. The nodes data
535 * will be set to NULL after the inner code, or when the inner code does
536 * '__stack[__slen]->data = NULL';
537 * The nodes are deleted automatically, so it is illegal to manually delete a
538 * node within this loop.
539 */
540#define tree64_foreach(__root, __data, __stack, __slen) \
541 for (__slen = 0, __stack[0] = __root, __data = NULL; ({ \
542 __label__ __left, __right, __again, __end; \
543 typeof(__root) __ptr = __stack[__slen]; \
544__again: \
545 if (__ptr->data != NULL) { \
546 __data = __ptr->data; \
547 goto __end; \
548 } \
549 else if (__ptr->left != NULL) { \
550 __stack[++__slen] = __ptr = __ptr->left; \
551 goto __again; \
552 } \
553 else \
554__left: \
555 if (__ptr->right != NULL) { \
556 __stack[++__slen] = __ptr = __ptr->right; \
557 goto __again; \
558 } \
559 else \
560__right: \
561 if (!__slen--) \
562 goto __end; /* nothing left, don't delete the root node */ \
563 else { \
564 typeof (__root) __old; \
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200565 pool_free2(pool2_tree64, __ptr); \
Willy Tarreaube384c62007-04-28 14:00:17 +0200566 __old = __ptr; \
567 __ptr = __stack[__slen]; \
568 if (__ptr->left == __old) { \
569 /* unlink this node from its parent */ \
570 __ptr->left = NULL; \
571 goto __left; \
572 } \
573 else { \
574 /* no need to unlink, the parent will also die */ \
575 goto __right; \
576 } \
577 } \
578__end: \
579 (__slen >= 0); }); ((typeof(__root))__stack[__slen])->data = NULL)
580
581
582
583/*
584 * walks down the tree <__root> and assigns <__node> to each of its nodes.
585 * <__stack> is an int array of at least N entries where N is the
586 * maximum number of levels of the tree. <__slen> is an integer variable used as
587 * a stack index. The instruction following the foreach statement is executed
588 * for each node.
589 * The tree will walk down only when the data field is empty (NULL), so it
590 * allows inner breaks, and will restart without losing items. The nodes data
591 * will be set to NULL after the inner code, or when the inner code does
592 * '__node->data = NULL';
593 * The nodes are deleted automatically, so it is illegal to manually delete a
594 * node within this loop.
595 */
596#define tree64_foreach_node(__root, __node, __stack, __slen) \
597 for (__slen = 0, __stack[0] = __root; ({ \
598 __label__ __left, __right, __again, __end; \
599 typeof(__root) __ptr = __stack[__slen]; \
600__again: \
601 if (__ptr->data != NULL) { \
602 __node = __ptr; \
603 goto __end; \
604 } \
605 else if (__ptr->left != NULL) { \
606 __stack[++__slen] = __ptr = __ptr->left; \
607 goto __again; \
608 } \
609 else \
610__left: \
611 if (__ptr->right != NULL) { \
612 __stack[++__slen] = __ptr = __ptr->right; \
613 goto __again; \
614 } \
615 else \
616__right: \
617 if (!__slen--) \
618 goto __end; /* nothing left, don't delete the root node */ \
619 else { \
620 typeof (__root) __old; \
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200621 pool_free2(pool2_tree64, __ptr); \
Willy Tarreaube384c62007-04-28 14:00:17 +0200622 __old = __ptr; \
623 __ptr = __stack[__slen]; \
624 if (__ptr->left == __old) { \
625 /* unlink this node from its parent */ \
626 __ptr->left = NULL; \
627 goto __left; \
628 } \
629 else { \
630 /* no need to unlink, the parent will also die */ \
631 goto __right; \
632 } \
633 } \
634__end: \
635 (__slen >= 0); }); ((typeof(__root))__stack[__slen])->data = NULL)
636
637
638/*
639 * removes the current node if possible, and its parent if it doesn't handle
640 * data. A pointer to the parent or grandparent is returned (the parent of the
641 * last one deleted in fact). This function should be compatible with any
642 * tree struct because of the void types.
643 * WARNING : never call it from within a tree_foreach() because this last one
644 * uses a stack which will not be updated.
645 */
646
647inline static void *__tree_delete_only_one(void *firstnode) {
648 struct tree64 *down, **uplink;
649 struct tree64 *node = firstnode;
650
651 /* don't kill the root or a populated link */
652 if (node->data || node->up == NULL)
653 return node;
654 if (node->left && node->right)
655 return node;
656 /* since we know that at least left or right is null, we can do arithmetics on them */
657 down = (void *)((long)node->left | (long)node->right);
658 /* find where we are linked */
659 if (node == node->up->left)
660 uplink = &node->up->left;
661 else
662 uplink = &node->up->right;
663
664 *uplink = down; /* we relink the lower branch above us or simply cut it */
665 if (down) {
666 down->up = node->up;
667 /* we know that we cannot do more because we kept one branch */
668 }
669 else {
670 /* we'll redo this once for the node above us because there was no branch below us,
671 * so maybe it doesn't need to exist for only one branch
672 */
673 down = node;
674 node = node->up;
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200675 pool_free2(pool2_tree64, down);
Willy Tarreaube384c62007-04-28 14:00:17 +0200676 if (node->data || node->up == NULL)
677 return node;
678 /* now we're sure we were sharing this empty node with another branch, let's find it */
679 down = (void *)((long)node->left | (long)node->right);
680 if (node == node->up->left)
681 uplink = &node->up->left;
682 else
683 uplink = &node->up->right;
684 *uplink = down; /* we relink the lower branch above */
685 down->up = node->up;
686 }
687 /* free the last node */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200688 pool_free2(pool2_tree64, node);
Willy Tarreaube384c62007-04-28 14:00:17 +0200689 return down->up;
690}
691
692/*
693 * removes the current node if possible, and all of its parents which do not
694 * carry data. A pointer to the parent of the last one deleted is returned.
695 * This function should be compatible with any tree struct because of the void
696 * types.
697 * WARNING : never call it from within a tree_foreach() because this last one
698 * uses a stack which will not be updated.
699 */
700
701inline static void *__tree_delete(void *firstnode) {
702 struct tree64 *down, **uplink, *up;
703 struct tree64 *node = firstnode;
704
705 while (1) {
706 /* don't kill the root or a populated link */
707 if (node->data || (up = node->up) == NULL)
708 return node;
709 if (node->left && node->right)
710 return node;
711 /* since we know that at least left or right is null, we can do arithmetics on them */
712 down = (void *)((long)node->left | (long)node->right);
713 /* find where we are linked */
714 if (node == up->left)
715 uplink = &up->left;
716 else
717 uplink = &up->right;
718
719 *uplink = down; /* we relink the lower branch above us or simply cut it */
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200720 pool_free2(pool2_tree64, node);
Willy Tarreaube384c62007-04-28 14:00:17 +0200721 node = up;
722 if (down)
723 down->up = node;
724 }
725}
726
727#endif /* __TREE_H__ */