2001-10-25 15:38:19 +04:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2007 Red Hat , Inc . All rights reserved .
2001-10-25 15:38:19 +04:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2001-10-25 15:38:19 +04:00
*/
2002-11-18 17:01:16 +03:00
# include "lib.h"
2001-10-25 15:38:19 +04:00
# include "btree.h"
struct node {
uint32_t key ;
struct node * l , * r , * p ;
void * data ;
} ;
struct btree {
2005-10-17 03:03:59 +04:00
struct dm_pool * mem ;
2001-10-25 15:38:19 +04:00
struct node * root ;
} ;
2005-10-17 03:03:59 +04:00
struct btree * btree_create ( struct dm_pool * mem )
2001-10-25 15:38:19 +04:00
{
2005-10-17 03:03:59 +04:00
struct btree * t = dm_pool_alloc ( mem , sizeof ( * t ) ) ;
2001-10-25 15:38:19 +04:00
if ( t ) {
t - > mem = mem ;
t - > root = NULL ;
}
return t ;
}
/*
* Shuffle the bits in a key , to try and remove
* any ordering .
*/
static uint32_t _shuffle ( uint32_t k )
{
2001-10-25 16:38:18 +04:00
# if 1
2001-10-25 15:38:19 +04:00
return ( ( k & 0xff ) < < 24 |
2001-10-25 16:38:18 +04:00
( k & 0xff00 ) < < 8 |
2002-04-24 22:20:51 +04:00
( k & 0xff0000 ) > > 8 | ( k & 0xff000000 ) > > 24 ) ;
2001-10-25 15:38:19 +04:00
# else
return k ;
# endif
}
2007-08-07 13:06:05 +04:00
static struct node * * _lookup ( struct node * const * c , uint32_t key ,
struct node * * p )
2001-10-25 15:38:19 +04:00
{
* p = NULL ;
while ( * c ) {
* p = * c ;
if ( ( * c ) - > key = = key )
break ;
if ( key < ( * c ) - > key )
c = & ( * c ) - > l ;
else
c = & ( * c ) - > r ;
}
2007-08-07 13:06:05 +04:00
return ( struct node * * ) c ;
2001-10-25 15:38:19 +04:00
}
2007-08-07 13:06:05 +04:00
void * btree_lookup ( const struct btree * t , uint32_t k )
2001-10-25 15:38:19 +04:00
{
uint32_t key = _shuffle ( k ) ;
struct node * p , * * c = _lookup ( & t - > root , key , & p ) ;
return ( * c ) ? ( * c ) - > data : NULL ;
}
int btree_insert ( struct btree * t , uint32_t k , void * data )
{
uint32_t key = _shuffle ( k ) ;
struct node * p , * * c = _lookup ( & t - > root , key , & p ) , * n ;
if ( ! * c ) {
2008-01-30 16:19:47 +03:00
if ( ! ( n = dm_pool_alloc ( t - > mem , sizeof ( * n ) ) ) )
return_0 ;
2001-10-25 15:38:19 +04:00
n - > key = key ;
n - > data = data ;
n - > l = n - > r = NULL ;
n - > p = p ;
* c = n ;
}
return 1 ;
}
2007-08-07 13:06:05 +04:00
void * btree_get_data ( const struct btree_iter * it )
2001-10-25 15:38:19 +04:00
{
return ( ( struct node * ) it ) - > data ;
}
2006-04-19 19:33:07 +04:00
static struct node * _left ( struct node * n )
2001-10-25 15:38:19 +04:00
{
while ( n - > l )
n = n - > l ;
return n ;
}
2007-08-07 13:06:05 +04:00
struct btree_iter * btree_first ( const struct btree * t )
2001-10-25 15:38:19 +04:00
{
if ( ! t - > root )
return NULL ;
return ( struct btree_iter * ) _left ( t - > root ) ;
}
2007-08-07 13:06:05 +04:00
struct btree_iter * btree_next ( const struct btree_iter * it )
2001-10-25 15:38:19 +04:00
{
struct node * n = ( struct node * ) it ;
uint32_t k = n - > key ;
if ( n - > r )
return ( struct btree_iter * ) _left ( n - > r ) ;
do
n = n - > p ;
while ( n & & k > n - > key ) ;
return ( struct btree_iter * ) n ;
}