[MEDIUM] upgrade to ebtree v4.0
New ebtree also supports unique keys. This is useful for counters.
diff --git a/include/common/eb32tree.h b/include/common/eb32tree.h
index f0c7930..6a39595 100644
--- a/include/common/eb32tree.h
+++ b/include/common/eb32tree.h
@@ -1,6 +1,7 @@
/*
* Elastic Binary Trees - macros and structures for operations on 32bit nodes.
- * (C) 2002-2007 - Willy Tarreau <w@1wt.eu>
+ * Version 4.0
+ * (C) 2002-2008 - 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
@@ -204,6 +205,7 @@
/* Insert eb32_node <new> into subtree starting at node root <root>.
* Only new->key needs be set with the key. The eb32_node is returned.
+ * If root->b[EB_RGHT]==1, the tree may only contain unique keys.
*/
static inline struct eb32_node *
__eb32_insert(struct eb_root *root, struct eb32_node *new) {
@@ -211,9 +213,11 @@
unsigned int side;
eb_troot_t *troot;
u32 newkey; /* caching the key saves approximately one cycle */
+ eb_troot_t *root_right = root;
side = EB_LEFT;
troot = root->b[EB_LEFT];
+ root_right = root->b[EB_RGHT];
if (unlikely(troot == NULL)) {
/* Tree is empty, insert the leaf part below the left branch */
root->b[EB_LEFT] = eb_dotag(&new->node.branches, EB_LEAF);
@@ -272,6 +276,12 @@
new->node.branches.b[EB_LEFT] = new_leaf;
new->node.branches.b[EB_RGHT] = old_leaf;
} else {
+ /* we may refuse to duplicate this key if the tree is
+ * tagged as containing only unique keys.
+ */
+ if ((new->key == old->key) && eb_gettag(root_right))
+ return old;
+
/* new->key >= old->key, new goes the right */
old->node.leaf_p = new_left;
new->node.leaf_p = new_rght;
@@ -359,7 +369,7 @@
/* Insert eb32_node <new> into subtree starting at node root <root>, using
* signed keys. Only new->key needs be set with the key. The eb32_node
- * is returned
+ * is returned. If root->b[EB_RGHT]==1, the tree may only contain unique keys.
*/
static inline struct eb32_node *
__eb32i_insert(struct eb_root *root, struct eb32_node *new) {
@@ -367,9 +377,11 @@
unsigned int side;
eb_troot_t *troot;
int newkey; /* caching the key saves approximately one cycle */
+ eb_troot_t *root_right = root;
side = EB_LEFT;
troot = root->b[EB_LEFT];
+ root_right = root->b[EB_RGHT];
if (unlikely(troot == NULL)) {
/* Tree is empty, insert the leaf part below the left branch */
root->b[EB_LEFT] = eb_dotag(&new->node.branches, EB_LEAF);
@@ -430,6 +442,12 @@
new->node.branches.b[EB_LEFT] = new_leaf;
new->node.branches.b[EB_RGHT] = old_leaf;
} else {
+ /* we may refuse to duplicate this key if the tree is
+ * tagged as containing only unique keys.
+ */
+ if ((new->key == old->key) && eb_gettag(root_right))
+ return old;
+
/* new->key >= old->key, new goes the right */
old->node.leaf_p = new_left;
new->node.leaf_p = new_rght;