1998-08-16 07:04:06 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1998-08-16 07:04:06 +04:00
simple bitmap functions
Copyright ( C ) Andrew Tridgell 1992 - 1998
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
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
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 . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
/* these functions provide a simple way to allocate integers from a
2001-10-29 11:26:45 +03:00
pool without repetition */
1998-08-16 07:04:06 +04:00
/****************************************************************************
allocate a bitmap of the specified size
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct bitmap * bitmap_allocate ( int n )
{
struct bitmap * bm ;
2004-12-07 21:25:53 +03:00
bm = SMB_MALLOC_P ( struct bitmap ) ;
1998-08-16 07:04:06 +04:00
if ( ! bm ) return NULL ;
1999-12-13 16:27:58 +03:00
bm - > n = n ;
2004-12-07 21:25:53 +03:00
bm - > b = SMB_MALLOC_ARRAY ( uint32 , ( n + 31 ) / 32 ) ;
1998-08-16 07:04:06 +04:00
if ( ! bm - > b ) {
2001-09-17 06:19:44 +04:00
SAFE_FREE ( bm ) ;
1998-08-16 07:04:06 +04:00
return NULL ;
}
2004-12-10 00:42:00 +03:00
memset ( bm - > b , 0 , sizeof ( uint32 ) * ( ( n + 31 ) / 32 ) ) ;
1998-08-16 07:04:06 +04:00
return bm ;
}
2001-03-11 03:32:10 +03:00
/****************************************************************************
free a bitmap .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void bitmap_free ( struct bitmap * bm )
{
if ( ! bm )
return ;
2001-09-17 06:19:44 +04:00
SAFE_FREE ( bm - > b ) ;
SAFE_FREE ( bm ) ;
2001-03-11 03:32:10 +03:00
}
2002-11-02 06:47:48 +03:00
/****************************************************************************
talloc a bitmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct bitmap * bitmap_talloc ( TALLOC_CTX * mem_ctx , int n )
{
struct bitmap * bm ;
if ( ! mem_ctx ) return NULL ;
2004-12-07 21:25:53 +03:00
bm = TALLOC_P ( mem_ctx , struct bitmap ) ;
2002-11-02 06:47:48 +03:00
if ( ! bm ) return NULL ;
bm - > n = n ;
2004-12-07 21:25:53 +03:00
bm - > b = TALLOC_ARRAY ( mem_ctx , uint32 , ( n + 31 ) / 32 ) ;
2002-11-02 06:47:48 +03:00
if ( ! bm - > b ) {
return NULL ;
}
2004-12-10 00:42:00 +03:00
memset ( bm - > b , 0 , sizeof ( uint32 ) * ( ( n + 31 ) / 32 ) ) ;
2002-11-02 06:47:48 +03:00
return bm ;
}
2003-12-11 23:00:16 +03:00
/****************************************************************************
copy as much of the source bitmap as will fit in the destination bitmap .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int bitmap_copy ( struct bitmap * const dst , const struct bitmap * const src )
{
int count = MIN ( dst - > n , src - > n ) ;
SMB_ASSERT ( dst - > b ! = src - > b ) ;
2004-12-10 00:42:00 +03:00
memcpy ( dst - > b , src - > b , sizeof ( uint32 ) * ( ( count + 31 ) / 32 ) ) ;
2003-12-11 23:00:16 +03:00
return count ;
}
1998-08-16 07:04:06 +04:00
/****************************************************************************
set a bit in a bitmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL bitmap_set ( struct bitmap * bm , unsigned i )
{
1998-08-17 07:06:20 +04:00
if ( i > = bm - > n ) {
DEBUG ( 0 , ( " Setting invalid bitmap entry %d (of %d) \n " ,
i , bm - > n ) ) ;
return False ;
}
1998-08-16 07:04:06 +04:00
bm - > b [ i / 32 ] | = ( 1 < < ( i % 32 ) ) ;
return True ;
}
/****************************************************************************
1998-08-16 08:08:47 +04:00
clear a bit in a bitmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL bitmap_clear ( struct bitmap * bm , unsigned i )
{
1998-08-17 07:06:20 +04:00
if ( i > = bm - > n ) {
DEBUG ( 0 , ( " clearing invalid bitmap entry %d (of %d) \n " ,
i , bm - > n ) ) ;
return False ;
}
1998-08-16 08:08:47 +04:00
bm - > b [ i / 32 ] & = ~ ( 1 < < ( i % 32 ) ) ;
return True ;
}
/****************************************************************************
1998-08-16 07:04:06 +04:00
query a bit in a bitmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-04 08:48:17 +04:00
BOOL bitmap_query ( struct bitmap * bm , unsigned i )
1998-08-16 07:04:06 +04:00
{
if ( i > = bm - > n ) return False ;
if ( bm - > b [ i / 32 ] & ( 1 < < ( i % 32 ) ) ) {
return True ;
}
return False ;
}
/****************************************************************************
find a zero bit in a bitmap starting at the specified offset , with
wraparound
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int bitmap_find ( struct bitmap * bm , unsigned ofs )
{
2003-02-01 10:25:53 +03:00
unsigned int i , j ;
1998-08-16 07:04:06 +04:00
if ( ofs > bm - > n ) ofs = 0 ;
i = ofs ;
while ( i < bm - > n ) {
if ( ~ ( bm - > b [ i / 32 ] ) ) {
j = i ;
do {
if ( ! bitmap_query ( bm , j ) ) return j ;
j + + ;
} while ( j & 31 & & j < bm - > n ) ;
}
i + = 32 ;
i & = ~ 31 ;
}
i = 0 ;
while ( i < ofs ) {
if ( ~ ( bm - > b [ i / 32 ] ) ) {
j = i ;
do {
if ( ! bitmap_query ( bm , j ) ) return j ;
j + + ;
} while ( j & 31 & & j < bm - > n ) ;
}
i + = 32 ;
i & = ~ 31 ;
}
return - 1 ;
}