[MEDIUM] ebtree: upgrade to version 6.0
This version adds support for prefix-based matching of memory blocks,
as well as some code-size and performance improvements on the generic
code. It provides a prefix insertion and longest match which are
compatible with the rest of the common features (walk, duplicates,
delete, ...). This is typically used for network address matching. The
longest-match code is a bit slower than the original memory block
handling code, so they have not been merged together into generic
code. Still it's possible to perform about 10 million networks lookups
per second in a set of 50000, so this should be enough for most usages.
This version also fixes some bugs in parts that were not used, so there
is no need to backport them.
diff --git a/ebtree/ebimtree.h b/ebtree/ebimtree.h
index f53a26a..4d2eea0 100644
--- a/ebtree/ebimtree.h
+++ b/ebtree/ebimtree.h
@@ -1,7 +1,7 @@
/*
* Elastic Binary Trees - macros for Indirect Multi-Byte data nodes.
- * Version 5.0
- * (C) 2002-2009 - Willy Tarreau <w@1wt.eu>
+ * Version 6.0
+ * (C) 2002-2010 - Willy Tarreau <w@1wt.eu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,7 +40,8 @@
{
struct ebpt_node *node;
eb_troot_t *troot;
- unsigned int bit;
+ int bit;
+ int node_bit;
troot = root->b[EB_LEFT];
if (unlikely(troot == NULL))
@@ -59,7 +60,8 @@
node = container_of(eb_untag(troot, EB_NODE),
struct ebpt_node, node.branches);
- if (node->node.bit < 0) {
+ node_bit = node->node.bit;
+ if (node_bit < 0) {
/* We have a dup tree now. Either it's for the same
* value, and we walk down left, or it's a different
* one and we don't have our key.
@@ -76,12 +78,12 @@
}
/* OK, normal data node, let's walk down */
- bit = equal_bits(x, node->key, bit, node->node.bit);
- if (bit < node->node.bit)
+ bit = equal_bits(x, node->key, bit, node_bit);
+ if (bit < node_bit)
return NULL; /* no more common bits */
- troot = node->node.branches.b[(((unsigned char*)x)[node->node.bit >> 3] >>
- (~node->node.bit & 7)) & 1];
+ troot = node->node.branches.b[(((unsigned char*)x)[node_bit >> 3] >>
+ (~node_bit & 7)) & 1];
}
}
@@ -99,6 +101,7 @@
eb_troot_t *root_right = root;
int diff;
int bit;
+ int old_node_bit;
side = EB_LEFT;
troot = root->b[EB_LEFT];
@@ -189,6 +192,7 @@
/* OK we're walking down this link */
old = container_of(eb_untag(troot, EB_NODE),
struct ebpt_node, node.branches);
+ old_node_bit = old->node.bit;
/* Stop going down when we don't have common bits anymore. We
* also stop in front of a duplicates tree because it means we
@@ -196,16 +200,16 @@
* the current node's because as long as they are identical, we
* know we descend along the correct side.
*/
- if (old->node.bit < 0) {
+ if (old_node_bit < 0) {
/* we're above a duplicate tree, we must compare till the end */
bit = equal_bits(new->key, old->key, bit, len);
goto dup_tree;
}
- else if (bit < old->node.bit) {
- bit = equal_bits(new->key, old->key, bit, old->node.bit);
+ else if (bit < old_node_bit) {
+ bit = equal_bits(new->key, old->key, bit, old_node_bit);
}
- if (bit < old->node.bit) { /* we don't have all bits in common */
+ if (bit < old_node_bit) { /* we don't have all bits in common */
/* The tree did not contain the key, so we insert <new> before the node
* <old>, and set ->bit to designate the lowest bit position in <new>
* which applies to ->branches.b[].
@@ -244,7 +248,7 @@
/* walk down */
root = &old->node.branches;
- side = (((unsigned char *)new->key)[old->node.bit >> 3] >> (~old->node.bit & 7)) & 1;
+ side = (((unsigned char *)new->key)[old_node_bit >> 3] >> (~old_node_bit & 7)) & 1;
troot = root->b[side];
}