bitmap就是用位来标记某种状态是否存在,这里我采用最小8位的uint8_t作为缓存,来减少浪费空间.
需要的内存空间为: uint8_t pool[n/8+1]
可简化为 uint8_t pool[(n>>3)+1]
置第n个位 先找到位于第几个索引 pool[n/8] 再进行取与求出对应的位置 n%8
pool[n/8]|=(1<<(n%8));
n=12; 索引 12/8=1 位置 12%8=4
求余可以用与符号取代
当x=2^n(n为自然数)时,
a % x = a & (x - 1 )
进一步简化为: poo[n>>3]|=(1<<(n&7));
typedef struct bitmap {
uint8_t* pool;
uint8_t bit_ndx_max;
uint32_t bit_max;
}bitmap_t;
#define BITMAP_NDX(bit) ((bit)>>3)
#define BITMAP_BIT(bit) (1<<((bit)&7))
#define BITMAP_EXCEEP -1
#define ERROR_NONE 0
void bitmap_create(bitmap_t* bitmap, uint8_t* pool, uint32_t bitmax)
{
bitmap->pool = pool;
bitmap->bit_ndx_max = (bitmax >> 3) + 1;
bitmap->bit_max = bitmax;
for (uint8_t i = 0;i < bitmap->bit_ndx_max;i++)
{
bitmap->pool[i] = 0;
}
}
uint8_t bitmap_set(bitmap_t* bitmap, uint32_t bit)
{
if (bit > bitmap->bit_max)
return BITMAP_EXCEEP;
bitmap->pool[BITMAP_NDX(bit)] |= BITMAP_BIT(bit);
return ERROR_NONE;
}
uint8_t bitmap_reset(bitmap_t* bitmap, uint32_t bit)
{
if (bit > bitmap->bit_max)
return BITMAP_EXCEEP;
bitmap->pool[BITMAP_NDX(bit)] &=~BITMAP_BIT(bit);
return ERROR_NONE;
}
uint8_t bitmap_is_set(bitmap_t* bitmap,uint32_t bit)
{
return !!(bitmap->pool[BITMAP_NDX(bit)]&BITMAP_BIT(bit));
}
uint32_t bitmap_count(bitmap_t* bitmap)
{
int count = 0;
for (uint32_t i = 0;i < bitmap->bit_ndx_max;i++)
{
int num = bitmap->pool[i];
while (num)
{
count++;
num &= num - 1;
}
}
return count;
}