2005-10-16 18:33:22 +04:00
/*
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
* Copyright ( C ) 2004 - 2005 Red Hat , Inc . All rights reserved .
*
* This file is part of the device - mapper userspace tools .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
* of the GNU General Public License v .2 .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include "lib.h"
/* FIXME: calculate this. */
# define INT_SHIFT 5
2005-10-17 02:57:20 +04:00
dm_bitset_t dm_bitset_create ( struct dm_pool * mem , unsigned num_bits )
2005-10-16 18:33:22 +04:00
{
2005-10-17 02:57:20 +04:00
unsigned n = ( num_bits / DM_BITS_PER_INT ) + 2 ;
2005-10-16 18:33:22 +04:00
size_t size = sizeof ( int ) * n ;
2005-10-17 02:57:20 +04:00
dm_bitset_t bs ;
2005-10-16 18:33:22 +04:00
if ( mem )
2005-10-17 02:57:20 +04:00
bs = dm_pool_zalloc ( mem , size ) ;
2005-10-16 18:33:22 +04:00
else
2005-10-17 02:57:20 +04:00
bs = dm_malloc ( size ) ;
2005-10-16 18:33:22 +04:00
if ( ! bs )
return NULL ;
* bs = num_bits ;
if ( ! mem )
2005-10-17 02:57:20 +04:00
dm_bit_clear_all ( bs ) ;
2005-10-16 18:33:22 +04:00
return bs ;
}
2005-10-17 02:57:20 +04:00
void dm_bitset_destroy ( dm_bitset_t bs )
2005-10-16 18:33:22 +04:00
{
2005-10-17 02:57:20 +04:00
dm_free ( bs ) ;
2005-10-16 18:33:22 +04:00
}
2005-10-17 02:57:20 +04:00
void dm_bit_union ( dm_bitset_t out , dm_bitset_t in1 , dm_bitset_t in2 )
2005-10-16 18:33:22 +04:00
{
int i ;
2005-10-17 02:57:20 +04:00
for ( i = ( in1 [ 0 ] / DM_BITS_PER_INT ) + 1 ; i ; i - - )
2005-10-16 18:33:22 +04:00
out [ i ] = in1 [ i ] | in2 [ i ] ;
}
/*
* FIXME : slow
*/
static inline int _test_word ( uint32_t test , int bit )
{
2006-01-31 17:50:38 +03:00
while ( bit < ( int ) DM_BITS_PER_INT ) {
2005-10-16 18:33:22 +04:00
if ( test & ( 0x1 < < bit ) )
return bit ;
bit + + ;
}
return - 1 ;
}
2005-10-17 02:57:20 +04:00
int dm_bit_get_next ( dm_bitset_t bs , int last_bit )
2005-10-16 18:33:22 +04:00
{
int bit , word ;
uint32_t test ;
last_bit + + ; /* otherwise we'll return the same bit again */
2006-01-31 17:50:38 +03:00
/*
* bs [ 0 ] holds number of bits
*/
while ( last_bit < ( int ) bs [ 0 ] ) {
2005-10-16 18:33:22 +04:00
word = last_bit > > INT_SHIFT ;
test = bs [ word + 1 ] ;
2005-10-17 02:57:20 +04:00
bit = last_bit & ( DM_BITS_PER_INT - 1 ) ;
2005-10-16 18:33:22 +04:00
if ( ( bit = _test_word ( test , bit ) ) > = 0 )
2005-10-17 02:57:20 +04:00
return ( word * DM_BITS_PER_INT ) + bit ;
2005-10-16 18:33:22 +04:00
2005-10-17 02:57:20 +04:00
last_bit = last_bit - ( last_bit & ( DM_BITS_PER_INT - 1 ) ) +
DM_BITS_PER_INT ;
2005-10-16 18:33:22 +04:00
}
return - 1 ;
}
2005-10-17 02:57:20 +04:00
int dm_bit_get_first ( dm_bitset_t bs )
2005-10-16 18:33:22 +04:00
{
2005-10-17 02:57:20 +04:00
return dm_bit_get_next ( bs , - 1 ) ;
2005-10-16 18:33:22 +04:00
}