2001-10-19 18:36:57 +04:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
2001-10-31 15:47:01 +03:00
* This file is released under the LGPL .
2001-10-19 18:36:57 +04:00
*/
2002-11-18 17:01:16 +03:00
# include "lib.h"
2001-10-19 18:36:57 +04:00
# include "bitset.h"
/* FIXME: calculate this. */
# define INT_SHIFT 5
2002-11-18 17:01:16 +03:00
bitset_t bitset_create ( struct pool * mem , unsigned num_bits )
2001-10-19 18:36:57 +04:00
{
2002-12-20 02:25:55 +03:00
unsigned n = ( num_bits / BITS_PER_INT ) + 2 ;
size_t size = sizeof ( int ) * n ;
2001-10-19 18:36:57 +04:00
unsigned * bs = pool_zalloc ( mem , size ) ;
if ( ! bs )
return NULL ;
* bs = num_bits ;
return bs ;
}
void bitset_destroy ( bitset_t bs )
{
dbg_free ( bs ) ;
}
void bit_union ( bitset_t out , bitset_t in1 , bitset_t in2 )
{
int i ;
2002-04-24 22:20:51 +04:00
for ( i = ( in1 [ 0 ] / BITS_PER_INT ) + 1 ; i ; i - - )
2001-10-19 18:36:57 +04:00
out [ i ] = in1 [ i ] | in2 [ i ] ;
}
/*
* FIXME : slow
*/
static inline int _test_word ( uint32_t test , int bit )
{
while ( bit < BITS_PER_INT ) {
if ( test & ( 0x1 < < bit ) )
return bit ;
bit + + ;
}
return - 1 ;
}
int bit_get_next ( bitset_t bs , int last_bit )
{
int bit , word ;
uint32_t test ;
last_bit + + ; /* otherwise we'll return the same bit again */
2002-04-24 22:20:51 +04:00
while ( last_bit < bs [ 0 ] ) {
2001-10-19 18:36:57 +04:00
word = last_bit > > INT_SHIFT ;
test = bs [ word + 1 ] ;
bit = last_bit & ( BITS_PER_INT - 1 ) ;
if ( ( bit = _test_word ( test , bit ) ) > = 0 )
return ( word * BITS_PER_INT ) + bit ;
2002-04-24 22:20:51 +04:00
last_bit = last_bit - ( last_bit & ( BITS_PER_INT - 1 ) ) +
BITS_PER_INT ;
2001-10-19 18:36:57 +04:00
}
return - 1 ;
}
int bit_get_first ( bitset_t bs )
{
return bit_get_next ( bs , - 1 ) ;
}