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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1998-08-16 07:04:06 +04:00
( 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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1998-08-16 07:04:06 +04:00
*/
2016-11-26 17:55:38 +03:00
# include "replace.h"
# include <talloc.h>
2011-07-07 15:04:31 +04:00
# include "lib/util/bitmap.h"
2016-11-26 17:55:38 +03:00
# include "lib/util/debug.h"
# include "lib/util/fault.h"
1998-08-16 07:04:06 +04:00
2012-10-31 01:43:21 +04:00
struct bitmap {
unsigned int n ;
2012-10-31 02:15:09 +04:00
uint32_t b [ 1 ] ; /* We allocate more */
2012-10-31 01:43:21 +04:00
} ;
1998-08-16 07:04:06 +04:00
/* 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
2002-11-02 06:47:48 +03:00
/****************************************************************************
talloc a bitmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct bitmap * bitmap_talloc ( TALLOC_CTX * mem_ctx , int n )
{
struct bitmap * bm ;
2012-10-31 02:15:09 +04:00
bm = ( struct bitmap * ) talloc_zero_size (
mem_ctx ,
offsetof ( struct bitmap , b ) + sizeof ( uint32_t ) * ( ( n + 31 ) / 32 ) ) ;
2002-11-02 06:47:48 +03:00
if ( ! bm ) return NULL ;
2009-08-07 14:09:21 +04:00
2012-10-31 02:15:09 +04:00
talloc_set_name_const ( bm , " struct bitmap " ) ;
2002-11-02 06:47:48 +03:00
bm - > n = n ;
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 ) ;
2011-07-07 15:04:31 +04:00
memcpy ( dst - > b , src - > b , sizeof ( uint32_t ) * ( ( 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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool bitmap_set ( struct bitmap * bm , unsigned i )
1998-08-16 07:04:06 +04:00
{
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 ) ) ;
2011-07-07 12:18:38 +04:00
return false ;
1998-08-17 07:06:20 +04:00
}
2018-11-22 17:06:42 +03:00
bm - > b [ i / 32 ] | = ( 1U < < ( i % 32 ) ) ;
2011-07-07 12:18:38 +04:00
return true ;
1998-08-16 07:04:06 +04:00
}
/****************************************************************************
1998-08-16 08:08:47 +04:00
clear a bit in a bitmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool bitmap_clear ( struct bitmap * bm , unsigned i )
1998-08-16 08:08:47 +04:00
{
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 ) ) ;
2011-07-07 12:18:38 +04:00
return false ;
1998-08-17 07:06:20 +04:00
}
2018-11-22 17:06:42 +03:00
bm - > b [ i / 32 ] & = ~ ( 1U < < ( i % 32 ) ) ;
2011-07-07 12:18:38 +04:00
return true ;
1998-08-16 08:08:47 +04:00
}
/****************************************************************************
1998-08-16 07:04:06 +04:00
query a bit in a bitmap
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool bitmap_query ( struct bitmap * bm , unsigned i )
1998-08-16 07:04:06 +04:00
{
2011-07-07 12:18:38 +04:00
if ( i > = bm - > n ) return false ;
2018-11-22 17:06:42 +03:00
if ( bm - > b [ i / 32 ] & ( 1U < < ( i % 32 ) ) ) {
2011-07-07 12:18:38 +04:00
return true ;
1998-08-16 07:04:06 +04:00
}
2011-07-07 12:18:38 +04:00
return false ;
1998-08-16 07:04:06 +04:00
}
/****************************************************************************
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 ;
}