2005-10-16 18:33:22 +04:00
/*
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 20:26:07 +04:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2005-10-16 18:33:22 +04:00
*
* 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
2007-08-21 20:26:07 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2005-10-16 18:33:22 +04:00
*
2007-08-21 20:26:07 +04:00
* You should have received a copy of the GNU Lesser General Public License
2005-10-16 18:33:22 +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
*/
2008-11-03 21:59:59 +03:00
# include "dmlib.h"
2005-10-16 18:33:22 +04:00
/* 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 ) ;
2010-10-01 01:06:50 +04:00
else
bs = dm_zalloc ( size ) ;
2005-10-16 18:33:22 +04:00
if ( ! bs )
return NULL ;
* bs = num_bits ;
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
}
2010-04-20 17:58:22 +04:00
int dm_bitset_equal ( dm_bitset_t in1 , dm_bitset_t in2 )
{
int i ;
for ( i = ( in1 [ 0 ] / DM_BITS_PER_INT ) + 1 ; i ; i - - )
if ( in1 [ i ] ! = in2 [ i ] )
return 0 ;
return 1 ;
}
2010-04-20 01:23:01 +04:00
void dm_bit_and ( dm_bitset_t out , dm_bitset_t in1 , dm_bitset_t in2 )
{
int i ;
for ( i = ( in1 [ 0 ] / DM_BITS_PER_INT ) + 1 ; i ; i - - )
out [ i ] = in1 [ i ] & in2 [ i ] ;
}
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 ] ;
}
2010-04-19 21:17:55 +04:00
static int _test_word ( uint32_t test , int bit )
2005-10-16 18:33:22 +04:00
{
2010-07-08 16:16:16 +04:00
uint32_t tb = test > > bit ;
2005-10-16 18:33:22 +04:00
2010-07-08 16:16:16 +04:00
return ( tb ? ffs ( tb ) + bit - 1 : - 1 ) ;
2005-10-16 18:33:22 +04:00
}
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
}