码迷,mamicode.com
首页 > 其他好文 > 详细

bitmap

时间:2016-04-16 13:59:30      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:

---恢复内容开始---

引入bit-map主要是为了节约内存,举个很简单的例子:服务器端要记录一些用户的ID,其实某些时候只是查询这个ID有没有被使用,或者分配一个没有使用的ID给用户,如果允许用户的量是1KW,使用数组的方式是建立一个数组,然后把每一个用户ID保存在数组中,按照用户量的要求,那么数组的类型是unsigned int 足足使用了4个字节,那么使用的空间是1KW * 4 = 4KW bytes。或者也可以用unsigned char 类型使用数组下标表示ID,元素的值取两个不同的值表示两种状态,那么量就是1KW bytes。有些时候为了分配和回收的方便,会再分配同样大小的数组,一个为空闲数组,一个为忙数组,这个时候存储容量会翻倍。显然这两种方法都消耗了大量的内存,既然数组的下标能表示ID,那为什么bit位的位置不能呢?

#include <stdio.h>
#include <string.h>
 
typedef struct BitMap
{
  unsigned long long *buffer;
  unsigned int size;
  unsigned int len;
  unsigned int free;
  unsigned int used;
  unsigned int curSort;
}BitMap;
 
int FindNextZeroBit(BitMap *map)
{
  int location = 0;
  int index = 0;
  int len = 0;
  int i = 0;
  int j = 0;
  int realsort = 0;
  unsigned char *p = NULL;
  unsigned char temp = 0;
 
  if(NULL == map)
  {  
    printf("%s the map is NULL\n",__FUNCTION__ );
    return -1;
  }
 
  if(NULL == map->buffer)
  {  
    printf("%s %d the bitmap‘s buffer is NULL\n", __FUNCTION__, __LINE__);
    return -1;
  }
 
  if(0 == map->free)
  {
    printf("%s %d there no zero bit\n", __FUNCTION__, __LINE__);
  }
 
  index = map->curSort;
  index >>= 3;
  len = map->len;
  len <<= 3;
  for(i=index; i<len+index; j=0)
  {
    realsort = i%len;
    p = (unsigned char *)(map->buffer + (realsort>>3));
    if(*((unsigned long long*)p) == 0xffffffffffffffff)
    {
      i -= i%8;
      i += 8;
      continue;
    }
 
    p += (realsort%8);
    if(0xff != *p)
    {
      while( j < 8 )
      {
        temp = (*p) & (1 << j);
        if(0 == temp)
        {
          location = (realsort<<3) + j;
          map->curSort = location;
          return location;
        }
        ++j;
      }
    }
    ++i;
  }
  return -1;
}
 
int InitOneBitMap(BitMap* map, unsigned int size)
{
  if(NULL == map)
  {
    return -1;
  }
 
  if(0 == size)
  {
    return -1;
  }
 
  map->len = size>>6;
  map->buffer = (unsigned long long*)malloc((map->len)<<3);
  if(NULL == map->buffer)
  {
    return -1;
  }
  memset(map->buffer, 0x00, (map->len)<<3);
  map->size = size;
  map->free = size;
  map->used = 0;
  map->curSort = 100;
 
  return 1;
}
 
int SetOneBit(BitMap *map, unsigned int location)
{
  if(NULL == map)
  {
    printf("%s the map is NULL\n", __FUNCTION__);  
    return -1;
  }
 
  if(location >= map->size)
  {
    printf("the location is bigger than size\n");
    return -1;
  }
 
  *(map->buffer+(location>>6)) |= ((unsigned long long)1<<(location%64));
  --map->free;
  ++map->used;
  return 1;
}
 
int ClearOneBit(BitMap* map,unsigned int location)
{
  if(NULL == map)
  {
    return -1;
  }
 
  if(location >= map->size)
  {
    return -1;
  }
 
  *(map->buffer+(location>>6)) &= ~((unsigned long long)1 << (location%64));
  ++map->free;
  --map->used;
  return 1;
}
 
int DestroyOneBitMap(BitMap* map)
{
  if(NULL == map)
  {
    return -1;
  }
 
  if(NULL != map->buffer)
  {
    free(map->buffer);
  }
 
  free(map);
  return 1;
}
 
int main(int argc, char *argv[])
{
  int i = 0;
  int pos = 0;
  int size = 0;
  BitMap *map = NULL;
   
  map = (BitMap*)malloc(sizeof(BitMap));
  if(NULL == map)
  {
    printf("alloc a map failed\n");
    return 0;
  }
  printf("alloc a bitmap success\n");
 
  printf("input the bit size: \n");
     scanf("%d", &size);
  InitOneBitMap(map, size);
  /*
  for(i=0; i< map->len; i++)
  {
    printf("buffer[%d] = %lx \n", i, map->buffer[i]);
  }
  */
 
    //using test
 
  /*
  for(i=0; i<4096; i++)
  {
    pos = FindNextZeroBit(map);
    printf("pos : %d\n", pos);
    if(-1 != pos)
    {
      SetOneBit(map, pos);
    }
  }
  */
  for(i=0; i<map->len; i++)
  {
    printf("buffer[%d] = %llx \n", i, map->buffer[i]);
  }
 
  DestroyOneBitMap(map);
 
  return 0;
}

       诚然bit-map可以解决存储的问题,但是另一个问题又会产生了。一个1KW级别的bit-map,如果使用率达到了90%以上,而且它的碎片存在不确定性,现在要求在这1KW级别的bit-map查找一个空闲的比特位,如果按照上面函数的方法,效率会很低下。考虑极端情况,未使用的bit位都在数组的最后面,那么99%的时间都浪费在前面的遍历数组。那这种情况如何尽量避免及解决呢? 管理数组!

bitmap

标签:

原文地址:http://www.cnblogs.com/liu-song/p/5398177.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!