| /* |
| * tree.h : tree manipulation macros and structures. |
| * (C) 2002 - Willy Tarreau - willy@ant-computing.com |
| * |
| */ |
| |
| #ifndef __TREE_H__ |
| #define __TREE_H__ |
| |
| #include <import/bitops.h> |
| #include <common/memory.h> |
| |
| /* binary tree node : either 32 bits unsigned long int values, or |
| * 64 bits in two 32 bits unsigned long int values |
| */ |
| struct ultree { |
| unsigned long low; /* 32 bits low value of this node */ |
| unsigned long high; /* 32 bits high value of this node, not used in 32 bits */ |
| int level; /* bit level of this node */ |
| void *data; /* carried data */ |
| struct ultree *left, *right; /* children : left and right. NULL = leaf */ |
| struct ultree *up; /* parent node. NULL = root */ |
| }; |
| |
| /* binary tree node : 64 bits unsigned long long values */ |
| struct ulltree { |
| unsigned long long value; /* 64 bits value of this node */ |
| int level; /* bit level of this node */ |
| void *data; /* carried data */ |
| struct ulltree *left, *right; /* children : left and right. NULL = leaf */ |
| struct ulltree *up; /* parent node. NULL = root */ |
| }; |
| |
| /* binary tree node : 64 bits in either one ull or two 32 bits unsigned long int values. This |
| * is the common type for all the above trees, which should be cast into it. This makes |
| * pool_free() far simpler since all types share a same pool. |
| */ |
| struct tree64 { |
| union { |
| struct { |
| unsigned long low; /* 32 bits low value of this node */ |
| unsigned long high; /* 32 bits high value of this node */ |
| } ul; |
| struct { |
| unsigned long long value; /* 64 bits value of this node */ |
| } ull; |
| } value; |
| int level; /* bit level of this node */ |
| void *data; /* carried data */ |
| struct tree64 *left, *right; /* children : left and right. NULL = leaf */ |
| struct tree64 *up; /* parent node. NULL = root */ |
| }; |
| |
| #define sizeof_tree64 (sizeof (struct tree64)) |
| extern void **pool_tree64; |
| |
| #define ULTREE_HEAD(l) struct ultree (l) = { .left=NULL, .right=NULL, .up=NULL, .low=0, .level=LONGBITS, .data=NULL } |
| #define ULTREE_INIT(l) { (l)->data = (l)->left = (l)->right = NULL; } |
| #define ULTREE_INIT_ROOT(l) { (l)->left=(l)->right=(l)->up=(l)->data=NULL; (l)->low=0; (l)->level=LONGBITS; } |
| |
| #define ULLTREE_HEAD(l) struct ulltree (l) = { .left=NULL, .right=NULL, .up=NULL, .value=0, .level=LLONGBITS, .data=NULL } |
| #define ULLTREE_INIT(l) { (l)->data = (l)->left = (l)->right = NULL; } |
| #define ULLTREE_INIT_ROOT(l) { (l)->left=(l)->right=(l)->up=(l)->data=NULL; (l)->value=0; (l)->level=LLONGBITS; } |
| |
| #define UL2TREE_HEAD(l) struct ultree (l) = { .left=NULL, .right=NULL, .up=NULL, .high=0, .low=0, .level=LLONGBITS, .data=NULL } |
| #define UL2TREE_INIT(l) { (l)->left = (l)->right = (l)->data = NULL; } |
| #define UL2TREE_INIT_ROOT(l) { (l)->left=(l)->right=(l)->up=(l)->data=NULL; (l)->high=(l)->low=0; (l)->level=LLONGBITS; } |
| |
| /* |
| * inserts necessary nodes to reach <x> in tree starting at <root>. The node |
| * is not created if it exists. It is returned. |
| */ |
| inline static struct ulltree *__ulltree_insert(struct ulltree *root, unsigned long long x) { |
| int m; |
| struct ulltree *next, *new, *node; |
| struct ulltree **branch; |
| int ffs; |
| |
| next = root; |
| ffs = ffs_fast64(x); |
| |
| do { |
| root = next; |
| |
| if (x == next->value) { |
| return next; |
| } |
| |
| if (x & (1ULL << (next->level - 1))) { /* right branch */ |
| branch = &next->right; |
| next = *branch; |
| } else { |
| branch = &next->left; |
| next = *branch; |
| } |
| |
| if (next == NULL) { |
| /* we'll have to insert our node here */ |
| *branch = new = (struct ulltree *)pool_alloc(tree64); |
| ULLTREE_INIT(new); |
| new->up = root; |
| new->value = x; |
| new->level = ffs; |
| return new; |
| } |
| |
| /* we'll keep walking down as long as we have all bits in common */ |
| } while ((x & ~((1ULL << next->level) - 1)) == next->value); |
| |
| |
| /* ok, now we know that we must insert between both. */ |
| |
| /* the new interconnect node */ |
| *branch = node = (struct ulltree *)pool_alloc(tree64); /* was <next> */ |
| ULLTREE_INIT(node); |
| node->up = root; |
| next->up = node; |
| |
| /* we need the common higher bits between x and next->value. */ |
| |
| /* what differences are there between x and the node here ? |
| * NOTE that m is always < level(parent) because highest bit |
| * of x and next-value are identical here (else they would be |
| * on a different branch). |
| */ |
| m = fls_fast64(x ^ next->value) + 1; /* m = lowest identical bit */ |
| node->value = x & ~((1ULL << m) - 1); /* value of common bits */ |
| |
| if (node->value == x) { /* <x> is exactly on this node */ |
| /* we must set its real position (eg: 8,10 => m=1 => val=8, m=3)*/ |
| node->level = ffs; |
| |
| if (next->value & (1ULL << (node->level - 1))) /* right branch */ |
| node->right = next; |
| else |
| node->left = next; |
| return node; |
| } |
| |
| /* the new leaf now */ |
| node->level = m; /* set the level to the lowest common bit */ |
| new = (struct ulltree *)pool_alloc(tree64); |
| ULLTREE_INIT(new); |
| new->value = x; |
| new->level = ffs; |
| |
| if (x > next->value) { |
| node->left = next; |
| node->right = new; |
| } |
| else { |
| node->left = new; |
| node->right = next; |
| } |
| new->up = node; |
| return new; |
| } |
| |
| /* |
| * inserts necessary nodes to reach <x> in tree starting at <root>. The node |
| * is not created if it exists. It is returned. |
| */ |
| inline static struct ultree *__ultree_insert(struct ultree *root, unsigned long x) { |
| int m; |
| struct ultree *next, *new, *node; |
| struct ultree **branch; |
| int ffs; |
| |
| next = root; |
| ffs = ffs_fast32(x); |
| |
| do { |
| root = next; |
| |
| if (x == next->low) { |
| return next; |
| } |
| |
| if ((x >> (next->level - 1)) & 1) { /* right branch */ |
| branch = &next->right; |
| next = *branch; |
| } else { |
| branch = &next->left; |
| next = *branch; |
| } |
| |
| if (next == NULL) { |
| /* we'll have to insert our node here */ |
| *branch = new = (struct ultree *)pool_alloc(tree64); |
| ULTREE_INIT(new); |
| new->up = root; |
| new->low = x; |
| new->level = ffs; |
| return new; |
| } |
| |
| /* we'll keep walking down as long as we have all bits in common */ |
| } while ((x & ~((1 << next->level) - 1)) == next->low); |
| |
| /* ok, now we know that we must insert between both. */ |
| |
| /* the new interconnect node */ |
| *branch = node = (struct ultree *)pool_alloc(tree64); /* was <next> */ |
| ULTREE_INIT(node); |
| node->up = root; |
| next->up = node; |
| |
| /* we need the common higher bits between x and next->low. */ |
| |
| /* what differences are there between x and the node here ? |
| * NOTE that m is always < level(parent) because highest bit |
| * of x and next->low are identical here (else they would be |
| * on a different branch). |
| */ |
| m = fls_fast32(x ^ next->low) + 1; /* m = lower identical bit */ |
| node->low = x & ~((1 << m) - 1); /* value of common bits */ |
| |
| if (node->low == x) { /* <x> is exactly on this node */ |
| /* we must set its real position (eg: 8,10 => m=1 => val=8, m=3)*/ |
| node->level = ffs; |
| |
| if (next->low & (1 << (node->level - 1))) /* right branch */ |
| node->right = next; |
| else |
| node->left = next; |
| return node; |
| } |
| |
| /* the new leaf now */ |
| node->level = m; /* set the level to the lowest common bit */ |
| new = (struct ultree *)pool_alloc(tree64); |
| ULTREE_INIT(new); |
| new->low = x; |
| new->level = ffs; |
| |
| if (x > next->low) { |
| node->left = next; |
| node->right = new; |
| } |
| else { |
| node->left = new; |
| node->right = next; |
| } |
| new->up = node; |
| return new; |
| } |
| |
| |
| /* |
| * inserts necessary nodes to reach <h:l> in tree starting at <root>. The node |
| * is not created if it exists. It is returned. |
| */ |
| inline static struct ultree *__ul2tree_insert(struct ultree *root, unsigned long h, unsigned long l) { |
| int m; |
| struct ultree *next, *new, *node; |
| struct ultree **branch; |
| |
| next = root; |
| |
| do { |
| root = next; |
| |
| if (h == next->high && l == next->low) { |
| return next; |
| } |
| |
| branch = &next->left; |
| if (next->level >= 33) { |
| if ((h >> (next->level - 33)) & 1) { /* right branch */ |
| branch = &next->right; |
| } |
| } |
| else { |
| if ((l >> (next->level - 1)) & 1) { /* right branch */ |
| branch = &next->right; |
| } |
| } |
| next = *branch; |
| |
| if (next == NULL) { |
| /* we'll have to insert our node here */ |
| *branch = new =(struct ultree *)pool_alloc(tree64); |
| UL2TREE_INIT(new); |
| new->up = root; |
| new->high = h; |
| new->low = l; |
| if (l) |
| new->level = __ffs_fast32(l); |
| else |
| new->level = __ffs_fast32(h) + 32; |
| |
| return new; |
| } |
| |
| /* we'll keep walking down as long as we have all bits in common */ |
| if (next->level >= 32) { |
| if ((h & ~((1 << (next->level-32)) - 1)) != next->high) |
| break; |
| } |
| else { |
| if (h != next->high) |
| break; |
| if ((l & ~((1 << next->level) - 1)) != next->low) |
| break; |
| } |
| } while (1); |
| |
| /* ok, now we know that we must insert between both. */ |
| |
| /* the new interconnect node */ |
| *branch = node = (struct ultree *)pool_alloc(tree64); /* was <next> */ |
| UL2TREE_INIT(node); |
| node->up = root; |
| next->up = node; |
| |
| /* we need the common higher bits between x and next->high:low. */ |
| |
| /* what differences are there between x and the node here ? |
| * NOTE that m is always < level(parent) because highest bit |
| * of x and next->high:low are identical here (else they would be |
| * on a different branch). |
| */ |
| if (h != next->high) { |
| m = fls_fast32(h ^ next->high) + 1; /* m = lower identical bit */ |
| node->high = h & ~((1 << m) - 1); /* value of common bits */ |
| m += 32; |
| node->low = 0; |
| } else { |
| node->high = h; |
| m = fls_fast32(l ^ next->low) + 1; /* m = lower identical bit */ |
| node->low = l & ~((1 << m) - 1); /* value of common bits */ |
| } |
| |
| if (node->high == h && node->low == l) { /* <h:l> is exactly on this node */ |
| /* we must set its real position (eg: 8,10 => m=1 => val=8, m=3)*/ |
| if (l) { |
| node->level = ffs_fast32(l); |
| if (next->low & (1 << (node->level - 1))) /* right branch */ |
| node->right = next; |
| else |
| node->left = next; |
| } |
| else { |
| node->level = ffs_fast32(h) + 32; |
| if (next->high & (1 << (node->level - 33))) /* right branch */ |
| node->right = next; |
| else |
| node->left = next; |
| } |
| return node; |
| } |
| |
| /* the new leaf now */ |
| node->level = m; /* set the level to the lowest common bit */ |
| new = (struct ultree *)pool_alloc(tree64); |
| UL2TREE_INIT(new); |
| new->high = h; |
| new->low = l; |
| if (l) |
| new->level = __ffs_fast32(l); |
| else |
| new->level = __ffs_fast32(h) + 32; |
| |
| if (h > next->high || (h == next->high && l > next->low)) { |
| node->left = next; |
| node->right = new; |
| } |
| else { |
| node->left = new; |
| node->right = next; |
| } |
| new->up = node; |
| return new; |
| } |
| |
| |
| /* |
| * finds a value in the tree <root>. If it cannot be found, NULL is returned. |
| */ |
| inline static struct ultree *__ultree_find(struct ultree *root, unsigned long x) { |
| do { |
| if (x == root->low) |
| return root; |
| |
| if ((x >> (root->level - 1)) & 1) |
| root = root->right; |
| else |
| root = root->left; |
| |
| if (root == NULL) |
| return NULL; |
| |
| /* we'll keep walking down as long as we have all bits in common */ |
| } while ((x & ~((1 << root->level) - 1)) == root->low); |
| |
| /* should be there, but nothing. */ |
| return NULL; |
| } |
| |
| /* |
| * finds a value in the tree <root>. If it cannot be found, NULL is returned. |
| */ |
| inline static struct ulltree *__ulltree_find(struct ulltree *root, unsigned long long x) { |
| do { |
| if (x == root->value) |
| return root; |
| |
| if ((x >> (root->level - 1)) & 1) |
| root = root->right; |
| else |
| root = root->left; |
| |
| if (root == NULL) |
| return NULL; |
| |
| /* we'll keep walking down as long as we have all bits in common */ |
| } while ((x & ~((1ULL << root->level) - 1)) == root->value); |
| |
| /* should be there, but nothing. */ |
| return NULL; |
| } |
| |
| |
| /* |
| * walks down the tree <__root> and assigns each of its data to <__data>. |
| * <__stack> is an int array of at least N entries where N is the maximum number |
| * of levels of the tree. <__slen> is an integer variable used as a stack index. |
| * The instruction following the foreach statement is executed for each data, |
| * after the data has been unlinked from the tree. |
| * The nodes are deleted automatically, so it is illegal to manually delete a |
| * node within this loop. |
| */ |
| #define tree64_foreach_destructive(__root, __data, __stack, __slen) \ |
| for (__slen = 0, __stack[0] = __root, __data = NULL; ({ \ |
| __label__ __left, __right, __again, __end; \ |
| typeof(__root) __ptr = __stack[__slen]; \ |
| __again: \ |
| __data = __ptr->data; \ |
| if (__data != NULL) { \ |
| __ptr->data = NULL; \ |
| goto __end; \ |
| } \ |
| else if (__ptr->left != NULL) { \ |
| __stack[++__slen] = __ptr = __ptr->left; \ |
| goto __again; \ |
| } \ |
| else \ |
| __left: \ |
| if (__ptr->right != NULL) { \ |
| __stack[++__slen] = __ptr = __ptr->right; \ |
| goto __again; \ |
| } \ |
| else \ |
| __right: \ |
| if (!__slen--) \ |
| goto __end; /* nothing left, don't delete the root node */ \ |
| else { \ |
| typeof (__root) __old; \ |
| pool_free(tree64, __ptr); \ |
| __old = __ptr; \ |
| __ptr = __stack[__slen]; \ |
| if (__ptr->left == __old) { \ |
| /* unlink this node from its parent */ \ |
| __ptr->left = NULL; \ |
| goto __left; \ |
| } \ |
| else { \ |
| /* no need to unlink, the parent will also die */ \ |
| goto __right; \ |
| } \ |
| } \ |
| __end: \ |
| (__slen >= 0); /* nothing after loop */}); ) |
| |
| |
| /* |
| * walks down the tree <__root> of type <__type> and assigns each of its data |
| * to <__data>. <__stack> is an int array of at least N entries where N is the |
| * maximum number of levels of the tree. <__slen> is an integer variable used |
| * as a stack index. The instruction following the foreach statement is |
| * executed for each data, after the data has been unlinked from the tree. |
| */ |
| #define tree_foreach_destructive(__type, __root, __data, __stack, __slen) \ |
| for (__slen = 0, __stack[0] = __root, __data = NULL; ({ \ |
| __label__ __left, __right, __again, __end; \ |
| typeof(__root) __ptr = __stack[__slen]; \ |
| __again: \ |
| __data = __ptr->data; \ |
| if (__data != NULL) { \ |
| __ptr->data = NULL; \ |
| goto __end; \ |
| } \ |
| else if (__ptr->left != NULL) { \ |
| __stack[++__slen] = __ptr = __ptr->left; \ |
| goto __again; \ |
| } \ |
| else \ |
| __left: \ |
| if (__ptr->right != NULL) { \ |
| __stack[++__slen] = __ptr = __ptr->right; \ |
| goto __again; \ |
| } \ |
| else \ |
| __right: \ |
| if (!__slen--) \ |
| goto __end; /* nothing left, don't delete the root node */ \ |
| else { \ |
| typeof (__root) __old; \ |
| pool_free(__type, __ptr); \ |
| __old = __ptr; \ |
| __ptr = __stack[__slen]; \ |
| if (__ptr->left == __old) { \ |
| /* unlink this node from its parent */ \ |
| __ptr->left = NULL; \ |
| goto __left; \ |
| } \ |
| else { \ |
| /* no need to unlink, the parent will also die */ \ |
| goto __right; \ |
| } \ |
| } \ |
| __end: \ |
| (__slen >= 0); /* nothing after loop */}); ) |
| |
| |
| /* |
| * walks down the tree <__root> and assigns <__data> a pointer to each of its |
| * data pointers. <__stack> is an int array of at least N entries where N is the |
| * maximum number of levels of the tree. <__slen> is an integer variable used as |
| * a stack index. The instruction following the foreach statement is executed |
| * for each data. |
| * The tree will walk down only when the data field is empty (NULL), so it |
| * allows inner breaks, and will restart without losing items. The nodes data |
| * will be set to NULL after the inner code, or when the inner code does |
| * '__stack[__slen]->data = NULL'; |
| * The nodes are deleted automatically, so it is illegal to manually delete a |
| * node within this loop. |
| */ |
| #define tree64_foreach(__root, __data, __stack, __slen) \ |
| for (__slen = 0, __stack[0] = __root, __data = NULL; ({ \ |
| __label__ __left, __right, __again, __end; \ |
| typeof(__root) __ptr = __stack[__slen]; \ |
| __again: \ |
| if (__ptr->data != NULL) { \ |
| __data = __ptr->data; \ |
| goto __end; \ |
| } \ |
| else if (__ptr->left != NULL) { \ |
| __stack[++__slen] = __ptr = __ptr->left; \ |
| goto __again; \ |
| } \ |
| else \ |
| __left: \ |
| if (__ptr->right != NULL) { \ |
| __stack[++__slen] = __ptr = __ptr->right; \ |
| goto __again; \ |
| } \ |
| else \ |
| __right: \ |
| if (!__slen--) \ |
| goto __end; /* nothing left, don't delete the root node */ \ |
| else { \ |
| typeof (__root) __old; \ |
| pool_free(tree64, __ptr); \ |
| __old = __ptr; \ |
| __ptr = __stack[__slen]; \ |
| if (__ptr->left == __old) { \ |
| /* unlink this node from its parent */ \ |
| __ptr->left = NULL; \ |
| goto __left; \ |
| } \ |
| else { \ |
| /* no need to unlink, the parent will also die */ \ |
| goto __right; \ |
| } \ |
| } \ |
| __end: \ |
| (__slen >= 0); }); ((typeof(__root))__stack[__slen])->data = NULL) |
| |
| |
| |
| /* |
| * walks down the tree <__root> and assigns <__node> to each of its nodes. |
| * <__stack> is an int array of at least N entries where N is the |
| * maximum number of levels of the tree. <__slen> is an integer variable used as |
| * a stack index. The instruction following the foreach statement is executed |
| * for each node. |
| * The tree will walk down only when the data field is empty (NULL), so it |
| * allows inner breaks, and will restart without losing items. The nodes data |
| * will be set to NULL after the inner code, or when the inner code does |
| * '__node->data = NULL'; |
| * The nodes are deleted automatically, so it is illegal to manually delete a |
| * node within this loop. |
| */ |
| #define tree64_foreach_node(__root, __node, __stack, __slen) \ |
| for (__slen = 0, __stack[0] = __root; ({ \ |
| __label__ __left, __right, __again, __end; \ |
| typeof(__root) __ptr = __stack[__slen]; \ |
| __again: \ |
| if (__ptr->data != NULL) { \ |
| __node = __ptr; \ |
| goto __end; \ |
| } \ |
| else if (__ptr->left != NULL) { \ |
| __stack[++__slen] = __ptr = __ptr->left; \ |
| goto __again; \ |
| } \ |
| else \ |
| __left: \ |
| if (__ptr->right != NULL) { \ |
| __stack[++__slen] = __ptr = __ptr->right; \ |
| goto __again; \ |
| } \ |
| else \ |
| __right: \ |
| if (!__slen--) \ |
| goto __end; /* nothing left, don't delete the root node */ \ |
| else { \ |
| typeof (__root) __old; \ |
| pool_free(tree64, __ptr); \ |
| __old = __ptr; \ |
| __ptr = __stack[__slen]; \ |
| if (__ptr->left == __old) { \ |
| /* unlink this node from its parent */ \ |
| __ptr->left = NULL; \ |
| goto __left; \ |
| } \ |
| else { \ |
| /* no need to unlink, the parent will also die */ \ |
| goto __right; \ |
| } \ |
| } \ |
| __end: \ |
| (__slen >= 0); }); ((typeof(__root))__stack[__slen])->data = NULL) |
| |
| |
| /* |
| * removes the current node if possible, and its parent if it doesn't handle |
| * data. A pointer to the parent or grandparent is returned (the parent of the |
| * last one deleted in fact). This function should be compatible with any |
| * tree struct because of the void types. |
| * WARNING : never call it from within a tree_foreach() because this last one |
| * uses a stack which will not be updated. |
| */ |
| |
| inline static void *__tree_delete_only_one(void *firstnode) { |
| struct tree64 *down, **uplink; |
| struct tree64 *node = firstnode; |
| |
| /* don't kill the root or a populated link */ |
| if (node->data || node->up == NULL) |
| return node; |
| if (node->left && node->right) |
| return node; |
| /* since we know that at least left or right is null, we can do arithmetics on them */ |
| down = (void *)((long)node->left | (long)node->right); |
| /* find where we are linked */ |
| if (node == node->up->left) |
| uplink = &node->up->left; |
| else |
| uplink = &node->up->right; |
| |
| *uplink = down; /* we relink the lower branch above us or simply cut it */ |
| if (down) { |
| down->up = node->up; |
| /* we know that we cannot do more because we kept one branch */ |
| } |
| else { |
| /* we'll redo this once for the node above us because there was no branch below us, |
| * so maybe it doesn't need to exist for only one branch |
| */ |
| down = node; |
| node = node->up; |
| pool_free(tree64, down); |
| if (node->data || node->up == NULL) |
| return node; |
| /* now we're sure we were sharing this empty node with another branch, let's find it */ |
| down = (void *)((long)node->left | (long)node->right); |
| if (node == node->up->left) |
| uplink = &node->up->left; |
| else |
| uplink = &node->up->right; |
| *uplink = down; /* we relink the lower branch above */ |
| down->up = node->up; |
| } |
| /* free the last node */ |
| pool_free(tree64, node); |
| return down->up; |
| } |
| |
| /* |
| * removes the current node if possible, and all of its parents which do not |
| * carry data. A pointer to the parent of the last one deleted is returned. |
| * This function should be compatible with any tree struct because of the void |
| * types. |
| * WARNING : never call it from within a tree_foreach() because this last one |
| * uses a stack which will not be updated. |
| */ |
| |
| inline static void *__tree_delete(void *firstnode) { |
| struct tree64 *down, **uplink, *up; |
| struct tree64 *node = firstnode; |
| |
| while (1) { |
| /* don't kill the root or a populated link */ |
| if (node->data || (up = node->up) == NULL) |
| return node; |
| if (node->left && node->right) |
| return node; |
| /* since we know that at least left or right is null, we can do arithmetics on them */ |
| down = (void *)((long)node->left | (long)node->right); |
| /* find where we are linked */ |
| if (node == up->left) |
| uplink = &up->left; |
| else |
| uplink = &up->right; |
| |
| *uplink = down; /* we relink the lower branch above us or simply cut it */ |
| pool_free(tree64, node); |
| node = up; |
| if (down) |
| down->up = node; |
| } |
| } |
| |
| #endif /* __TREE_H__ */ |