@ -1,4 +1,4 @@
/* Copyright (C) 2000 MySQL AB
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
@ -91,6 +91,7 @@ static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused)))
# endif
}
static inline void bitmap_unlock ( MY_BITMAP * map __attribute__ ( ( unused ) ) )
{
# ifdef THREAD
@ -100,6 +101,46 @@ static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused)))
}
static inline uint get_first_set ( uint32 value , uint word_pos )
{
uchar * byte_ptr = ( uchar * ) & value ;
uchar byte_value ;
uint byte_pos , bit_pos ;
for ( byte_pos = 0 ; byte_pos < 4 ; byte_pos + + , byte_ptr + + )
{
byte_value = * byte_ptr ;
if ( byte_value )
{
for ( bit_pos = 0 ; ; bit_pos + + )
if ( byte_value & ( 1 < < bit_pos ) )
return ( word_pos * 32 ) + ( byte_pos * 8 ) + bit_pos ;
}
}
return MY_BIT_NONE ;
}
static inline uint get_first_not_set ( uint32 value , uint word_pos )
{
uchar * byte_ptr = ( uchar * ) & value ;
uchar byte_value ;
uint byte_pos , bit_pos ;
for ( byte_pos = 0 ; byte_pos < 4 ; byte_pos + + , byte_ptr + + )
{
byte_value = * byte_ptr ;
if ( byte_value ! = 0xFF )
{
for ( bit_pos = 0 ; ; bit_pos + + )
if ( ! ( byte_value & ( 1 < < bit_pos ) ) )
return ( word_pos * 32 ) + ( byte_pos * 8 ) + bit_pos ;
}
}
return MY_BIT_NONE ;
}
my_bool bitmap_init ( MY_BITMAP * map , my_bitmap_map * buf , uint n_bits ,
my_bool thread_safe __attribute__ ( ( unused ) ) )
{
@ -259,7 +300,7 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
memset ( m , 0xff , prefix_bytes ) ;
m + = prefix_bytes ;
if ( ( prefix_bits = prefix_size & 7 ) )
* m + + = ( 1 < < prefix_bits ) - 1 ;
* ( m + + ) = ( 1 < < prefix_bits ) - 1 ;
if ( ( d = no_bytes_in_map ( map ) - prefix_bytes ) )
bzero ( m , d ) ;
}
@ -267,28 +308,43 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
my_bool bitmap_is_prefix ( const MY_BITMAP * map , uint prefix_size )
{
uint prefix_bits = prefix_size & 0x7 , res ;
uchar * m = ( uchar * ) map - > bitmap ;
uchar * end_prefix = m + prefix_size / 8 ;
uchar * end ;
DBUG_ASSERT ( m & & prefix_size < = map - > n_bits ) ;
end = m + no_bytes_in_map ( map ) ;
while ( m < end_prefix )
if ( * m + + ! = 0xff )
return 0 ;
* map - > last_word_ptr & = ~ map - > last_word_mask ; /*Clear bits*/
res = 0 ;
if ( prefix_bits & & * m + + ! = ( 1 < < prefix_bits ) - 1 )
goto ret ;
while ( m < end )
if ( * m + + ! = 0 )
goto ret ;
res = 1 ;
ret :
return res ;
uint prefix_bits = prefix_size % 32 ;
my_bitmap_map * word_ptr = map - > bitmap , last_word ;
my_bitmap_map * end_prefix = word_ptr + prefix_size / 32 ;
DBUG_ASSERT ( word_ptr & & prefix_size < = map - > n_bits ) ;
/* 1: Words that should be filled with 1 */
for ( ; word_ptr < end_prefix ; word_ptr + + )
if ( * word_ptr ! = 0xFFFFFFFF )
return FALSE ;
last_word = * map - > last_word_ptr & ~ map - > last_word_mask ;
/* 2: Word which contains the end of the prefix (if any) */
if ( prefix_bits )
{
if ( word_ptr = = map - > last_word_ptr )
return uint4korr ( ( uchar * ) & last_word ) = = ( uint32 ) ( ( 1 < < prefix_bits ) - 1 ) ;
else if ( uint4korr ( ( uchar * ) word_ptr ) ! = ( uint32 ) ( ( 1 < < prefix_bits ) - 1 ) )
return FALSE ;
word_ptr + + ;
}
/* 3: Words that should be filled with 0 */
for ( ; word_ptr < map - > last_word_ptr ; word_ptr + + )
if ( * word_ptr ! = 0 )
return FALSE ;
/*
We can end up here in two situations :
1 ) We went through the whole bitmap in step 1. This will happen if the
whole bitmap is filled with 1 and prefix_size is a multiple of 32
( i . e . the prefix does not end in the middle of a word ) .
In this case word_ptr will be larger than map - > last_word_ptr .
2 ) We have gone through steps 1 - 3 and just need to check that also
the last word is 0.
*/
return word_ptr > map - > last_word_ptr | | last_word = = 0 ;
}
@ -296,10 +352,12 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map)
{
my_bitmap_map * data_ptr = map - > bitmap ;
my_bitmap_map * end = map - > last_word_ptr ;
* map - > last_word_ptr | = map - > last_word_mask ;
for ( ; data_ptr < = end ; data_ptr + + )
for ( ; data_ptr < end ; data_ptr + + )
if ( * data_ptr ! = 0xFFFFFFFF )
return FALSE ;
if ( ( * map - > last_word_ptr | map - > last_word_mask ) ! = 0xFFFFFFFF )
return FALSE ;
return TRUE ;
}
@ -307,13 +365,13 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map)
my_bool bitmap_is_clear_all ( const MY_BITMAP * map )
{
my_bitmap_map * data_ptr = map - > bitmap ;
my_bitmap_map * end ;
if ( * map - > last_word_ptr & ~ map - > last_word_mask )
return FALSE ;
end = map - > last_word_ptr ;
my_bitmap_map * end = map - > last_word_ptr ;
for ( ; data_ptr < end ; data_ptr + + )
if ( * data_ptr )
return FALSE ;
if ( * map - > last_word_ptr & ~ map - > last_word_mask )
return FALSE ;
return TRUE ;
}
@ -327,14 +385,14 @@ my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
map1 - > n_bits = = map2 - > n_bits ) ;
end = map1 - > last_word_ptr ;
* map1 - > last_word_ptr & = ~ map1 - > last_word_mask ;
* map2 - > last_word_ptr & = ~ map2 - > last_word_mask ;
while ( m1 < = end )
{
if ( ( * m1 + + ) & ~ ( * m2 + + ) )
return 0 ;
}
return 1 ;
for ( ; m1 < end ; m1 + + , m2 + + )
if ( * m1 & ~ ( * m2 ) )
return FALSE ;
if ( ( * map1 - > last_word_ptr & ~ map1 - > last_word_mask ) &
~ ( * map2 - > last_word_ptr & ~ map2 - > last_word_mask ) )
return FALSE ;
return TRUE ;
}
/* True if bitmaps has any common bits */
@ -347,14 +405,14 @@ my_bool bitmap_is_overlapping(const MY_BITMAP *map1, const MY_BITMAP *map2)
map1 - > n_bits = = map2 - > n_bits ) ;
end = map1 - > last_word_ptr ;
* map1 - > last_word_ptr & = ~ map1 - > last_word_mask ;
* map2 - > last_word_ptr & = ~ map2 - > last_word_mask ;
while ( m1 < = end )
{
if ( ( * m1 + + ) & ( * m2 + + ) )
return 1 ;
}
return 0 ;
for ( ; m1 < end ; m1 + + , m2 + + )
if ( * m1 & * m2 )
return TRUE ;
if ( ( * map1 - > last_word_ptr & ~ map1 - > last_word_mask ) &
( * map2 - > last_word_ptr & ~ map2 - > last_word_mask ) )
return TRUE ;
return FALSE ;
}
@ -366,15 +424,17 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
DBUG_ASSERT ( map - > bitmap & & map2 - > bitmap ) ;
end = to + min ( len , len2 ) ;
* map2 - > last_word_ptr & = ~ map2 - > last_word_mask ; /*Clear last bits in map2*/
while ( to < end )
* to + + & = * from + + ;
for ( ; to < end ; to + + , from + + )
* to & = * from ;
if ( len > = len2 )
map - > bitmap [ len2 - 1 ] & = ~ map2 - > last_word_mask ;
if ( len2 < len )
{
end + = len - len2 ;
while ( to < end )
* to + + = 0 ;
for ( ; to < end ; to + + )
* to = 0 ;
}
}
@ -405,8 +465,8 @@ void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit)
uchar * to = ( uchar * ) map - > bitmap + from_byte ;
uchar * end = ( uchar * ) map - > bitmap + ( map - > n_bits + 7 ) / 8 ;
while ( to < end )
* to + + = use_byte ;
for ( ; to < end ; to + + )
* to = use_byte ;
}
@ -415,59 +475,60 @@ void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
my_bitmap_map * to = map - > bitmap , * from = map2 - > bitmap , * end ;
DBUG_ASSERT ( map - > bitmap & & map2 - > bitmap & &
map - > n_bits = = map2 - > n_bits ) ;
end = map - > last_word_ptr ;
while ( to < = end )
* to + + & = ~ ( * from + + ) ;
for ( ; to < = end ; to + + , from + + )
* to & = ~ ( * from ) ;
}
void bitmap_union ( MY_BITMAP * map , const MY_BITMAP * map2 )
{
my_bitmap_map * to = map - > bitmap , * from = map2 - > bitmap , * end ;
DBUG_ASSERT ( map - > bitmap & & map2 - > bitmap & &
map - > n_bits = = map2 - > n_bits ) ;
end = map - > last_word_ptr ;
while ( to < = end )
* to + + | = * from + + ;
for ( ; to < = end ; to + + , from + + )
* to | = * from ;
}
void bitmap_xor ( MY_BITMAP * map , const MY_BITMAP * map2 )
{
my_bitmap_map * to = map - > bitmap , * from = map2 - > bitmap , * end = map - > last_word_ptr ;
my_bitmap_map * to = map - > bitmap , * from = map2 - > bitmap , * end ;
DBUG_ASSERT ( map - > bitmap & & map2 - > bitmap & &
map - > n_bits = = map2 - > n_bits ) ;
while ( to < = end )
* to + + ^ = * from + + ;
end = map - > last_word_ptr ;
for ( ; to < = end ; to + + , from + + )
* to ^ = * from ;
}
void bitmap_invert ( MY_BITMAP * map )
{
my_bitmap_map * to = map - > bitmap , * end ;
DBUG_ASSERT ( map - > bitmap ) ;
end = map - > last_word_ptr ;
while ( to < = end )
* to + + ^ = 0xFFFFFFFF ;
for ( ; to < = end ; to + + )
* to ^ = 0xFFFFFFFF ;
}
uint bitmap_bits_set ( const MY_BITMAP * map )
{
uchar * m = ( uchar * ) map - > bitmap ;
uchar * end = m + no_bytes_in_map ( map ) ;
{
my_bitmap_map * data_ptr = map - > bitmap ;
my_bitmap_map * end = map - > last_word_ptr ;
uint res = 0 ;
DBUG_ASSERT ( map - > bitmap ) ;
* map - > last_word_ptr & = ~ map - > last_word_mask ; /*Reset last bits to zero*/
while ( m < end )
res + = my_count_bits_ushort ( * m + + ) ;
for ( ; data_ptr < end ; data_ptr + + )
res + = my_count_bits_uint32 ( * data_ptr ) ;
/*Reset last bits to zero*/
res + = my_count_bits_uint32 ( * map - > last_word_ptr & ~ map - > last_word_mask ) ;
return res ;
}
@ -475,76 +536,44 @@ uint bitmap_bits_set(const MY_BITMAP *map)
void bitmap_copy ( MY_BITMAP * map , const MY_BITMAP * map2 )
{
my_bitmap_map * to = map - > bitmap , * from = map2 - > bitmap , * end ;
DBUG_ASSERT ( map - > bitmap & & map2 - > bitmap & &
map - > n_bits = = map2 - > n_bits ) ;
end = map - > last_word_ptr ;
while ( to < = end )
* to + + = * from + + ;
for ( ; to < = end ; to + + , from + + )
* to = * from ;
}
uint bitmap_get_first_set ( const MY_BITMAP * map )
{
uchar * byte_ptr ;
uint i , j , k ;
uint word_pos ;
my_bitmap_map * data_ptr , * end = map - > last_word_ptr ;
DBUG_ASSERT ( map - > bitmap ) ;
data_ptr = map - > bitmap ;
* map - > last_word_ptr & = ~ map - > last_word_mask ;
for ( i = 0 ; data_ptr < = end ; data_ptr + + , i + + )
{
for ( word_pos = 0 ; data_ptr < end ; data_ptr + + , word_pos + + )
if ( * data_ptr )
{
byte_ptr = ( uchar * ) data_ptr ;
for ( j = 0 ; ; j + + , byte_ptr + + )
{
if ( * byte_ptr )
{
for ( k = 0 ; ; k + + )
{
if ( * byte_ptr & ( 1 < < k ) )
return ( i * 32 ) + ( j * 8 ) + k ;
}
}
}
}
}
return MY_BIT_NONE ;
return get_first_set ( * data_ptr , word_pos ) ;
return get_first_set ( * map - > last_word_ptr & ~ map - > last_word_mask , word_pos ) ;
}
uint bitmap_get_first ( const MY_BITMAP * map )
{
uchar * byte_ptr ;
uint i , j , k ;
uint word_pos ;
my_bitmap_map * data_ptr , * end = map - > last_word_ptr ;
DBUG_ASSERT ( map - > bitmap ) ;
data_ptr = map - > bitmap ;
* map - > last_word_ptr | = map - > last_word_mask ;
for ( i = 0 ; data_ptr < = end ; data_ptr + + , i + + )
{
for ( word_pos = 0 ; data_ptr < end ; data_ptr + + , word_pos + + )
if ( * data_ptr ! = 0xFFFFFFFF )
{
byte_ptr = ( uchar * ) data_ptr ;
for ( j = 0 ; ; j + + , byte_ptr + + )
{
if ( * byte_ptr ! = 0xFF )
{
for ( k = 0 ; ; k + + )
{
if ( ! ( * byte_ptr & ( 1 < < k ) ) )
return ( i * 32 ) + ( j * 8 ) + k ;
}
}
}
}
}
return MY_BIT_NONE ;
return get_first_not_set ( * data_ptr , word_pos ) ;
return get_first_not_set ( * map - > last_word_ptr | map - > last_word_mask , word_pos ) ;
}
@ -752,375 +781,3 @@ void bitmap_lock_flip_bit(MY_BITMAP *map, uint bitmap_bit)
bitmap_unlock ( map ) ;
}
# endif
# ifdef MAIN
uint get_rand_bit ( uint bitsize )
{
return ( rand ( ) % bitsize ) ;
}
bool test_set_get_clear_bit ( MY_BITMAP * map , uint bitsize )
{
uint i , test_bit ;
uint no_loops = bitsize > 128 ? 128 : bitsize ;
for ( i = 0 ; i < no_loops ; i + + )
{
test_bit = get_rand_bit ( bitsize ) ;
bitmap_set_bit ( map , test_bit ) ;
if ( ! bitmap_is_set ( map , test_bit ) )
goto error1 ;
bitmap_clear_bit ( map , test_bit ) ;
if ( bitmap_is_set ( map , test_bit ) )
goto error2 ;
}
return FALSE ;
error1 :
printf ( " Error in set bit, bit %u, bitsize = %u " , test_bit , bitsize ) ;
return TRUE ;
error2 :
printf ( " Error in clear bit, bit %u, bitsize = %u " , test_bit , bitsize ) ;
return TRUE ;
}
bool test_flip_bit ( MY_BITMAP * map , uint bitsize )
{
uint i , test_bit ;
uint no_loops = bitsize > 128 ? 128 : bitsize ;
for ( i = 0 ; i < no_loops ; i + + )
{
test_bit = get_rand_bit ( bitsize ) ;
bitmap_flip_bit ( map , test_bit ) ;
if ( ! bitmap_is_set ( map , test_bit ) )
goto error1 ;
bitmap_flip_bit ( map , test_bit ) ;
if ( bitmap_is_set ( map , test_bit ) )
goto error2 ;
}
return FALSE ;
error1 :
printf ( " Error in flip bit 1, bit %u, bitsize = %u " , test_bit , bitsize ) ;
return TRUE ;
error2 :
printf ( " Error in flip bit 2, bit %u, bitsize = %u " , test_bit , bitsize ) ;
return TRUE ;
}
bool test_operators ( MY_BITMAP * map __attribute__ ( ( unused ) ) ,
uint bitsize __attribute__ ( ( unused ) ) )
{
return FALSE ;
}
bool test_get_all_bits ( MY_BITMAP * map , uint bitsize )
{
uint i ;
bitmap_set_all ( map ) ;
if ( ! bitmap_is_set_all ( map ) )
goto error1 ;
if ( ! bitmap_is_prefix ( map , bitsize ) )
goto error5 ;
bitmap_clear_all ( map ) ;
if ( ! bitmap_is_clear_all ( map ) )
goto error2 ;
if ( ! bitmap_is_prefix ( map , 0 ) )
goto error6 ;
for ( i = 0 ; i < bitsize ; i + + )
bitmap_set_bit ( map , i ) ;
if ( ! bitmap_is_set_all ( map ) )
goto error3 ;
for ( i = 0 ; i < bitsize ; i + + )
bitmap_clear_bit ( map , i ) ;
if ( ! bitmap_is_clear_all ( map ) )
goto error4 ;
return FALSE ;
error1 :
printf ( " Error in set_all, bitsize = %u " , bitsize ) ;
return TRUE ;
error2 :
printf ( " Error in clear_all, bitsize = %u " , bitsize ) ;
return TRUE ;
error3 :
printf ( " Error in bitmap_is_set_all, bitsize = %u " , bitsize ) ;
return TRUE ;
error4 :
printf ( " Error in bitmap_is_clear_all, bitsize = %u " , bitsize ) ;
return TRUE ;
error5 :
printf ( " Error in set_all through set_prefix, bitsize = %u " , bitsize ) ;
return TRUE ;
error6 :
printf ( " Error in clear_all through set_prefix, bitsize = %u " , bitsize ) ;
return TRUE ;
}
bool test_compare_operators ( MY_BITMAP * map , uint bitsize )
{
uint i , j , test_bit1 , test_bit2 , test_bit3 , test_bit4 ;
uint no_loops = bitsize > 128 ? 128 : bitsize ;
MY_BITMAP map2_obj , map3_obj ;
MY_BITMAP * map2 = & map2_obj , * map3 = & map3_obj ;
my_bitmap_map map2buf [ 1024 ] ;
my_bitmap_map map3buf [ 1024 ] ;
bitmap_init ( & map2_obj , map2buf , bitsize , FALSE ) ;
bitmap_init ( & map3_obj , map3buf , bitsize , FALSE ) ;
bitmap_clear_all ( map2 ) ;
bitmap_clear_all ( map3 ) ;
for ( i = 0 ; i < no_loops ; i + + )
{
test_bit1 = get_rand_bit ( bitsize ) ;
bitmap_set_prefix ( map , test_bit1 ) ;
test_bit2 = get_rand_bit ( bitsize ) ;
bitmap_set_prefix ( map2 , test_bit2 ) ;
bitmap_intersect ( map , map2 ) ;
test_bit3 = test_bit2 < test_bit1 ? test_bit2 : test_bit1 ;
bitmap_set_prefix ( map3 , test_bit3 ) ;
if ( ! bitmap_cmp ( map , map3 ) )
goto error1 ;
bitmap_clear_all ( map ) ;
bitmap_clear_all ( map2 ) ;
bitmap_clear_all ( map3 ) ;
test_bit1 = get_rand_bit ( bitsize ) ;
test_bit2 = get_rand_bit ( bitsize ) ;
test_bit3 = get_rand_bit ( bitsize ) ;
bitmap_set_prefix ( map , test_bit1 ) ;
bitmap_set_prefix ( map2 , test_bit2 ) ;
test_bit3 = test_bit2 > test_bit1 ? test_bit2 : test_bit1 ;
bitmap_set_prefix ( map3 , test_bit3 ) ;
bitmap_union ( map , map2 ) ;
if ( ! bitmap_cmp ( map , map3 ) )
goto error2 ;
bitmap_clear_all ( map ) ;
bitmap_clear_all ( map2 ) ;
bitmap_clear_all ( map3 ) ;
test_bit1 = get_rand_bit ( bitsize ) ;
test_bit2 = get_rand_bit ( bitsize ) ;
test_bit3 = get_rand_bit ( bitsize ) ;
bitmap_set_prefix ( map , test_bit1 ) ;
bitmap_set_prefix ( map2 , test_bit2 ) ;
bitmap_xor ( map , map2 ) ;
test_bit3 = test_bit2 > test_bit1 ? test_bit2 : test_bit1 ;
test_bit4 = test_bit2 < test_bit1 ? test_bit2 : test_bit1 ;
bitmap_set_prefix ( map3 , test_bit3 ) ;
for ( j = 0 ; j < test_bit4 ; j + + )
bitmap_clear_bit ( map3 , j ) ;
if ( ! bitmap_cmp ( map , map3 ) )
goto error3 ;
bitmap_clear_all ( map ) ;
bitmap_clear_all ( map2 ) ;
bitmap_clear_all ( map3 ) ;
test_bit1 = get_rand_bit ( bitsize ) ;
test_bit2 = get_rand_bit ( bitsize ) ;
test_bit3 = get_rand_bit ( bitsize ) ;
bitmap_set_prefix ( map , test_bit1 ) ;
bitmap_set_prefix ( map2 , test_bit2 ) ;
bitmap_subtract ( map , map2 ) ;
if ( test_bit2 < test_bit1 )
{
bitmap_set_prefix ( map3 , test_bit1 ) ;
for ( j = 0 ; j < test_bit2 ; j + + )
bitmap_clear_bit ( map3 , j ) ;
}
if ( ! bitmap_cmp ( map , map3 ) )
goto error4 ;
bitmap_clear_all ( map ) ;
bitmap_clear_all ( map2 ) ;
bitmap_clear_all ( map3 ) ;
test_bit1 = get_rand_bit ( bitsize ) ;
bitmap_set_prefix ( map , test_bit1 ) ;
bitmap_invert ( map ) ;
bitmap_set_all ( map3 ) ;
for ( j = 0 ; j < test_bit1 ; j + + )
bitmap_clear_bit ( map3 , j ) ;
if ( ! bitmap_cmp ( map , map3 ) )
goto error5 ;
bitmap_clear_all ( map ) ;
bitmap_clear_all ( map3 ) ;
}
return FALSE ;
error1 :
printf ( " intersect error bitsize=%u,size1=%u,size2=%u " , bitsize ,
test_bit1 , test_bit2 ) ;
return TRUE ;
error2 :
printf ( " union error bitsize=%u,size1=%u,size2=%u " , bitsize ,
test_bit1 , test_bit2 ) ;
return TRUE ;
error3 :
printf ( " xor error bitsize=%u,size1=%u,size2=%u " , bitsize ,
test_bit1 , test_bit2 ) ;
return TRUE ;
error4 :
printf ( " subtract error bitsize=%u,size1=%u,size2=%u " , bitsize ,
test_bit1 , test_bit2 ) ;
return TRUE ;
error5 :
printf ( " invert error bitsize=%u,size=%u " , bitsize ,
test_bit1 ) ;
return TRUE ;
}
bool test_count_bits_set ( MY_BITMAP * map , uint bitsize )
{
uint i , bit_count = 0 , test_bit ;
uint no_loops = bitsize > 128 ? 128 : bitsize ;
for ( i = 0 ; i < no_loops ; i + + )
{
test_bit = get_rand_bit ( bitsize ) ;
if ( ! bitmap_is_set ( map , test_bit ) )
{
bitmap_set_bit ( map , test_bit ) ;
bit_count + + ;
}
}
if ( bit_count = = 0 & & bitsize > 0 )
goto error1 ;
if ( bitmap_bits_set ( map ) ! = bit_count )
goto error2 ;
return FALSE ;
error1 :
printf ( " No bits set bitsize = %u " , bitsize ) ;
return TRUE ;
error2 :
printf ( " Wrong count of bits set, bitsize = %u " , bitsize ) ;
return TRUE ;
}
bool test_get_first_bit ( MY_BITMAP * map , uint bitsize )
{
uint i , test_bit ;
uint no_loops = bitsize > 128 ? 128 : bitsize ;
for ( i = 0 ; i < no_loops ; i + + )
{
test_bit = get_rand_bit ( bitsize ) ;
bitmap_set_bit ( map , test_bit ) ;
if ( bitmap_get_first_set ( map ) ! = test_bit )
goto error1 ;
bitmap_set_all ( map ) ;
bitmap_clear_bit ( map , test_bit ) ;
if ( bitmap_get_first ( map ) ! = test_bit )
goto error2 ;
bitmap_clear_all ( map ) ;
}
return FALSE ;
error1 :
printf ( " get_first_set error bitsize=%u,prefix_size=%u " , bitsize , test_bit ) ;
return TRUE ;
error2 :
printf ( " get_first error bitsize= %u, prefix_size= %u " , bitsize , test_bit ) ;
return TRUE ;
}
bool test_get_next_bit ( MY_BITMAP * map , uint bitsize )
{
uint i , j , test_bit ;
uint no_loops = bitsize > 128 ? 128 : bitsize ;
for ( i = 0 ; i < no_loops ; i + + )
{
test_bit = get_rand_bit ( bitsize ) ;
for ( j = 0 ; j < test_bit ; j + + )
bitmap_set_next ( map ) ;
if ( ! bitmap_is_prefix ( map , test_bit ) )
goto error1 ;
bitmap_clear_all ( map ) ;
}
return FALSE ;
error1 :
printf ( " get_next error bitsize= %u, prefix_size= %u " , bitsize , test_bit ) ;
return TRUE ;
}
bool test_prefix ( MY_BITMAP * map , uint bitsize )
{
uint i , j , test_bit ;
uint no_loops = bitsize > 128 ? 128 : bitsize ;
for ( i = 0 ; i < no_loops ; i + + )
{
test_bit = get_rand_bit ( bitsize ) ;
bitmap_set_prefix ( map , test_bit ) ;
if ( ! bitmap_is_prefix ( map , test_bit ) )
goto error1 ;
bitmap_clear_all ( map ) ;
for ( j = 0 ; j < test_bit ; j + + )
bitmap_set_bit ( map , j ) ;
if ( ! bitmap_is_prefix ( map , test_bit ) )
goto error2 ;
bitmap_set_all ( map ) ;
for ( j = bitsize - 1 ; ~ ( j - test_bit ) ; j - - )
bitmap_clear_bit ( map , j ) ;
if ( ! bitmap_is_prefix ( map , test_bit ) )
goto error3 ;
bitmap_clear_all ( map ) ;
}
return FALSE ;
error1 :
printf ( " prefix1 error bitsize = %u, prefix_size = %u " , bitsize , test_bit ) ;
return TRUE ;
error2 :
printf ( " prefix2 error bitsize = %u, prefix_size = %u " , bitsize , test_bit ) ;
return TRUE ;
error3 :
printf ( " prefix3 error bitsize = %u, prefix_size = %u " , bitsize , test_bit ) ;
return TRUE ;
}
bool do_test ( uint bitsize )
{
MY_BITMAP map ;
my_bitmap_map buf [ 1024 ] ;
if ( bitmap_init ( & map , buf , bitsize , FALSE ) )
{
printf ( " init error for bitsize %d " , bitsize ) ;
goto error ;
}
if ( test_set_get_clear_bit ( & map , bitsize ) )
goto error ;
bitmap_clear_all ( & map ) ;
if ( test_flip_bit ( & map , bitsize ) )
goto error ;
bitmap_clear_all ( & map ) ;
if ( test_operators ( & map , bitsize ) )
goto error ;
bitmap_clear_all ( & map ) ;
if ( test_get_all_bits ( & map , bitsize ) )
goto error ;
bitmap_clear_all ( & map ) ;
if ( test_compare_operators ( & map , bitsize ) )
goto error ;
bitmap_clear_all ( & map ) ;
if ( test_count_bits_set ( & map , bitsize ) )
goto error ;
bitmap_clear_all ( & map ) ;
if ( test_get_first_bit ( & map , bitsize ) )
goto error ;
bitmap_clear_all ( & map ) ;
if ( test_get_next_bit ( & map , bitsize ) )
goto error ;
if ( test_prefix ( & map , bitsize ) )
goto error ;
return FALSE ;
error :
printf ( " \n " ) ;
return TRUE ;
}
int main ( )
{
int i ;
for ( i = 1 ; i < 4096 ; i + + )
{
printf ( " Start test for bitsize=%u \n " , i ) ;
if ( do_test ( i ) )
return - 1 ;
}
printf ( " OK \n " ) ;
return 0 ;
}
/*
In directory mysys :
make test_bitmap
will build the bitmap tests and . / test_bitmap will execute it
*/
# endif