2009-10-26 19:48:54 +01:00
/*
* Elastic Binary Trees - macros to manipulate String data nodes .
2011-07-25 11:38:17 +02:00
* Version 6.0 .6
2011-01-04 14:33:13 +01:00
* ( C ) 2002 - 2011 - Willy Tarreau < w @ 1 wt . eu >
2009-10-26 19:48:54 +01:00
*
2011-07-25 11:38:17 +02:00
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation , version 2.1
* exclusively .
2009-10-26 19:48:54 +01:00
*
2011-07-25 11:38:17 +02:00
* This library is distributed in the hope that it will be useful ,
2009-10-26 19:48:54 +01:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2011-07-25 11:38:17 +02:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
2009-10-26 19:48:54 +01:00
*
2011-07-25 11:38:17 +02:00
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2009-10-26 19:48:54 +01:00
*/
/* These functions and macros rely on Multi-Byte nodes */
2009-11-02 14:43:39 +01:00
# ifndef _EBSTTREE_H
# define _EBSTTREE_H
2009-10-26 19:48:54 +01:00
# include "ebtree.h"
# include "ebmbtree.h"
/* The following functions are not inlined by default. They are declared
* in ebsttree . c , which simply relies on their inline version .
*/
REGPRM2 struct ebmb_node * ebst_lookup ( struct eb_root * root , const char * x ) ;
REGPRM2 struct ebmb_node * ebst_insert ( struct eb_root * root , struct ebmb_node * new ) ;
2011-01-04 14:33:13 +01:00
/* Find the first occurence of a length <len> string <x> in the tree <root>.
* It ' s the caller ' s reponsibility to use this function only on trees which
* only contain zero - terminated strings , and that no null character is present
* in string < x > in the first < len > chars . If none can be found , return NULL .
*/
static forceinline struct ebmb_node *
ebst_lookup_len ( struct eb_root * root , const char * x , unsigned int len )
{
struct ebmb_node * node ;
node = ebmb_lookup ( root , x , len ) ;
if ( ! node | | node - > key [ len ] ! = 0 )
return NULL ;
return node ;
}
2009-10-26 19:48:54 +01:00
/* Find the first occurence of a zero-terminated string <x> in the tree <root>.
* It ' s the caller ' s reponsibility to use this function only on trees which
* only contain zero - terminated strings . If none can be found , return NULL .
*/
static forceinline struct ebmb_node * __ebst_lookup ( struct eb_root * root , const void * x )
{
struct ebmb_node * node ;
eb_troot_t * troot ;
2010-05-09 19:29:23 +02:00
int bit ;
int node_bit ;
2009-10-26 19:48:54 +01:00
troot = root - > b [ EB_LEFT ] ;
if ( unlikely ( troot = = NULL ) )
return NULL ;
bit = 0 ;
while ( 1 ) {
if ( ( eb_gettag ( troot ) = = EB_LEAF ) ) {
node = container_of ( eb_untag ( troot , EB_LEAF ) ,
struct ebmb_node , node . branches ) ;
2009-10-29 12:00:11 +01:00
if ( strcmp ( ( char * ) node - > key , x ) = = 0 )
2009-10-26 19:48:54 +01:00
return node ;
else
return NULL ;
}
node = container_of ( eb_untag ( troot , EB_NODE ) ,
struct ebmb_node , node . branches ) ;
2010-05-09 19:29:23 +02:00
node_bit = node - > node . bit ;
2009-10-26 19:48:54 +01:00
2010-05-09 19:29:23 +02:00
if ( node_bit < 0 ) {
2009-10-26 19:48:54 +01:00
/* 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 .
*/
2009-10-29 12:00:11 +01:00
if ( strcmp ( ( char * ) node - > key , x ) ! = 0 )
2009-10-26 19:48:54 +01:00
return NULL ;
troot = node - > node . branches . b [ EB_LEFT ] ;
while ( eb_gettag ( troot ) ! = EB_LEAF )
troot = ( eb_untag ( troot , EB_NODE ) ) - > b [ EB_LEFT ] ;
node = container_of ( eb_untag ( troot , EB_LEAF ) ,
struct ebmb_node , node . branches ) ;
return node ;
}
2010-10-28 22:48:29 +02:00
/* OK, normal data node, let's walk down but don't compare data
* if we already reached the end of the key .
*/
if ( likely ( bit > = 0 ) ) {
bit = string_equal_bits ( x , node - > key , bit ) ;
if ( likely ( bit < node_bit ) ) {
if ( bit > = 0 )
return NULL ; /* no more common bits */
/* bit < 0 : we reached the end of the key. If we
* are in a tree with unique keys , we can return
* this node . Otherwise we have to walk it down
* and stop comparing bits .
*/
if ( eb_gettag ( root - > b [ EB_RGHT ] ) )
return node ;
}
2011-11-14 14:09:27 +01:00
/* if the bit is larger than the node's, we must bound it
* because we might have compared too many bytes with an
* inappropriate leaf . For a test , build a tree from " 0 " ,
* " WW " , " W " , " S " inserted in this exact sequence and lookup
* " W " = > " S " is returned without this assignment .
*/
else
bit = node_bit ;
2010-10-28 22:48:29 +02:00
}
2009-10-26 19:48:54 +01:00
2010-05-09 19:29:23 +02:00
troot = node - > node . branches . b [ ( ( ( unsigned char * ) x ) [ node_bit > > 3 ] > >
( ~ node_bit & 7 ) ) & 1 ] ;
2009-10-26 19:48:54 +01:00
}
}
/* Insert ebmb_node <new> into subtree starting at node root <root>. Only
* new - > key needs be set with the zero - terminated string key . The ebmb_node is
* returned . If root - > b [ EB_RGHT ] = = 1 , the tree may only contain unique keys . The
* caller is responsible for properly terminating the key with a zero .
*/
static forceinline struct ebmb_node *
__ebst_insert ( struct eb_root * root , struct ebmb_node * new )
{
struct ebmb_node * old ;
unsigned int side ;
eb_troot_t * troot ;
2011-09-19 20:48:00 +02:00
eb_troot_t * root_right ;
2009-10-26 19:48:54 +01:00
int diff ;
int bit ;
2010-05-09 19:29:23 +02:00
int old_node_bit ;
2009-10-26 19:48:54 +01:00
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 ) ;
new - > node . leaf_p = eb_dotag ( root , EB_LEFT ) ;
new - > node . node_p = NULL ; /* node part unused */
return new ;
}
/* The tree descent is fairly easy :
* - first , check if we have reached a leaf node
* - second , check if we have gone too far
* - third , reiterate
* Everywhere , we use < new > for the node node we are inserting , < root >
* for the node we attach it to , and < old > for the node we are
* displacing below < new > . < troot > will always point to the future node
* ( tagged with its type ) . < side > carries the side the node < new > is
* attached to below its parent , which is also where previous node
* was attached .
*/
bit = 0 ;
while ( 1 ) {
if ( unlikely ( eb_gettag ( troot ) = = EB_LEAF ) ) {
eb_troot_t * new_left , * new_rght ;
eb_troot_t * new_leaf , * old_leaf ;
old = container_of ( eb_untag ( troot , EB_LEAF ) ,
struct ebmb_node , node . branches ) ;
new_left = eb_dotag ( & new - > node . branches , EB_LEFT ) ;
new_rght = eb_dotag ( & new - > node . branches , EB_RGHT ) ;
new_leaf = eb_dotag ( & new - > node . branches , EB_LEAF ) ;
old_leaf = eb_dotag ( & old - > node . branches , EB_LEAF ) ;
new - > node . node_p = old - > node . leaf_p ;
/* Right here, we have 3 possibilities :
* - the tree does not contain the key , and we have
* new - > key < old - > key . We insert new above old , on
* the left ;
*
* - the tree does not contain the key , and we have
* new - > key > old - > key . We insert new above old , on
* the right ;
*
* - the tree does contain the key , which implies it
* is alone . We add the new key next to it as a
* first duplicate .
*
* The last two cases can easily be partially merged .
*/
2010-10-28 22:48:29 +02:00
if ( bit > = 0 )
bit = string_equal_bits ( new - > key , old - > key , bit ) ;
if ( bit < 0 ) {
/* key was already there */
2009-10-26 19:48:54 +01:00
/* we may refuse to duplicate this key if the tree is
* tagged as containing only unique keys .
*/
2010-10-28 22:48:29 +02:00
if ( eb_gettag ( root_right ) )
2009-10-26 19:48:54 +01:00
return old ;
2010-10-28 22:48:29 +02:00
/* new arbitrarily goes to the right and tops the dup tree */
2009-10-26 19:48:54 +01:00
old - > node . leaf_p = new_left ;
new - > node . leaf_p = new_rght ;
new - > node . branches . b [ EB_LEFT ] = old_leaf ;
new - > node . branches . b [ EB_RGHT ] = new_leaf ;
2010-10-28 22:48:29 +02:00
new - > node . bit = - 1 ;
root - > b [ side ] = eb_dotag ( & new - > node . branches , EB_NODE ) ;
return new ;
}
2009-10-26 19:48:54 +01:00
2010-10-28 22:48:29 +02:00
diff = cmp_bits ( new - > key , old - > key , bit ) ;
if ( diff < 0 ) {
/* new->key < old->key, new takes the left */
new - > node . leaf_p = new_left ;
old - > node . leaf_p = new_rght ;
new - > node . branches . b [ EB_LEFT ] = new_leaf ;
new - > node . branches . b [ EB_RGHT ] = old_leaf ;
} else {
/* new->key > old->key, new takes the right */
old - > node . leaf_p = new_left ;
new - > node . leaf_p = new_rght ;
new - > node . branches . b [ EB_LEFT ] = old_leaf ;
new - > node . branches . b [ EB_RGHT ] = new_leaf ;
2009-10-26 19:48:54 +01:00
}
break ;
}
/* OK we're walking down this link */
old = container_of ( eb_untag ( troot , EB_NODE ) ,
struct ebmb_node , node . branches ) ;
2010-05-09 19:29:23 +02:00
old_node_bit = old - > node . bit ;
2009-10-26 19:48:54 +01:00
/* Stop going down when we don't have common bits anymore. We
* also stop in front of a duplicates tree because it means we
* have to insert above . Note : we can compare more bits than
* the current node ' s because as long as they are identical , we
* know we descend along the correct side .
*/
2010-10-28 22:48:29 +02:00
if ( bit > = 0 & & ( bit < old_node_bit | | old_node_bit < 0 ) )
2009-10-26 19:48:54 +01:00
bit = string_equal_bits ( new - > key , old - > key , bit ) ;
2010-10-28 22:48:29 +02:00
if ( unlikely ( bit < 0 ) ) {
/* Perfect match, we must only stop on head of dup tree
* or walk down to a leaf .
*/
if ( old_node_bit < 0 ) {
/* We know here that string_equal_bits matched all
* bits and that we ' re on top of a dup tree , then
* we can perform the dup insertion and return .
*/
struct eb_node * ret ;
ret = eb_insert_dup ( & old - > node , & new - > node ) ;
return container_of ( ret , struct ebmb_node , node ) ;
}
/* OK so let's walk down */
}
else if ( bit < old_node_bit | | old_node_bit < 0 ) {
/* The tree did not contain the key, or we stopped on top of a dup
* tree , possibly containing the key . In the former case , we insert
* < new > before the node < old > , and set - > bit to designate the lowest
* bit position in < new > which applies to - > branches . b [ ] . In the later
* case , we add the key to the existing dup tree . Note that we cannot
* enter here if we match an intermediate node ' s key that is not the
* head of a dup tree .
2009-10-26 19:48:54 +01:00
*/
eb_troot_t * new_left , * new_rght ;
eb_troot_t * new_leaf , * old_node ;
2010-10-28 22:48:29 +02:00
2009-10-26 19:48:54 +01:00
new_left = eb_dotag ( & new - > node . branches , EB_LEFT ) ;
new_rght = eb_dotag ( & new - > node . branches , EB_RGHT ) ;
new_leaf = eb_dotag ( & new - > node . branches , EB_LEAF ) ;
old_node = eb_dotag ( & old - > node . branches , EB_NODE ) ;
new - > node . node_p = old - > node . node_p ;
2010-10-28 22:48:29 +02:00
/* we can never match all bits here */
2009-10-26 19:48:54 +01:00
diff = cmp_bits ( new - > key , old - > key , bit ) ;
if ( diff < 0 ) {
new - > node . leaf_p = new_left ;
old - > node . node_p = new_rght ;
new - > node . branches . b [ EB_LEFT ] = new_leaf ;
new - > node . branches . b [ EB_RGHT ] = old_node ;
}
2010-10-28 22:48:29 +02:00
else {
2009-10-26 19:48:54 +01:00
old - > node . node_p = new_left ;
new - > node . leaf_p = new_rght ;
new - > node . branches . b [ EB_LEFT ] = old_node ;
new - > node . branches . b [ EB_RGHT ] = new_leaf ;
}
break ;
}
/* walk down */
root = & old - > node . branches ;
2010-05-09 19:29:23 +02:00
side = ( new - > key [ old_node_bit > > 3 ] > > ( ~ old_node_bit & 7 ) ) & 1 ;
2009-10-26 19:48:54 +01:00
troot = root - > b [ side ] ;
}
/* Ok, now we are inserting <new> between <root> and <old>. <old>'s
* parent is already set to < new > , and the < root > ' s branch is still in
* < side > . Update the root ' s leaf till we have it . Note that we can also
* find the side by checking the side of new - > node . node_p .
*/
/* We need the common higher bits between new->key and old->key.
* This number of bits is already in < bit > .
2010-10-28 22:48:29 +02:00
* NOTE : we can ' t get here whit bit < 0 since we found a dup !
2009-10-26 19:48:54 +01:00
*/
new - > node . bit = bit ;
root - > b [ side ] = eb_dotag ( & new - > node . branches , EB_NODE ) ;
return new ;
}
2009-11-02 14:43:39 +01:00
# endif /* _EBSTTREE_H */