bitmap就是位图,在处理大数据时必不可少,来看下实现:
#include "util/tc_bitmap.h"
#include "util/tc_common.h"
#include <cassert>
#include <string.h>
#include <iostream>
namespace tars
{
const int TC_BitMap::BitMap::_magic_bits[8]={0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
size_t TC_BitMap::BitMap::calcMemSize(size_t iElementCount)
{
assert(iElementCount > 0);
iElementCount--;
size_t iMemSize = iElementCount/8+1;
iMemSize += sizeof(tagBitMapHead);
return iMemSize;
}
void TC_BitMap::BitMap::create(void *pAddr, size_t iSize)
{
memset((char*)pAddr, 0, iSize);
_pHead = static_cast<tagBitMapHead*>(pAddr);
_pHead->_cVersion = BM_VERSION;
_pHead->_iMemSize = iSize;
_pData = (unsigned char*)pAddr + sizeof(tagBitMapHead);
}
int TC_BitMap::BitMap::connect(void *pAddr, size_t iSize)
{
_pHead = static_cast<tagBitMapHead*>(pAddr);
if(_pHead->_cVersion != BM_VERSION)
{
return -1;
}
if(iSize != _pHead->_iMemSize)
{
return -2;
}
_pData = (unsigned char*)pAddr + sizeof(tagBitMapHead);
return 0;
}
int TC_BitMap::BitMap::get(size_t i)
{
if(i/8 >= (_pHead->_iMemSize-sizeof(tagBitMapHead)))
{
return -1;
}
unsigned char* p =_pData + i/8;
return _get_bit(*p, i%8)>0?1:0;
}
int TC_BitMap::BitMap::set(size_t i)
{
if(i/8 >= (_pHead->_iMemSize-sizeof(tagBitMapHead)))
{
return -1;
}
unsigned char* p=(unsigned char*)_pData + i/8;
*p = _set_bit(*p, i%8);
return (int)(*p)>0?1:0;
}
int TC_BitMap::BitMap::clear(size_t i)
{
if(i/8 >= (_pHead->_iMemSize-sizeof(tagBitMapHead)))
{
return -1;
}
unsigned char* p = (unsigned char*)_pData + i/8;
*p = _clear_bit(*p, i%8);
return (int)(*p)>0?1:0;
}
int TC_BitMap::BitMap::clear4all()
{
memset(_pData, 0, _pHead->_iMemSize-sizeof(tagBitMapHead));
return 0;
}
int TC_BitMap::BitMap::dump2file(const string &sFile)
{
FILE *fp = fopen(sFile.c_str(), "wb");
if(fp == NULL)
{
return -1;
}
size_t ret = fwrite((void*)_pHead, 1, _pHead->_iMemSize, fp);
fclose(fp);
if(ret == _pHead->_iMemSize)
{
return 0;
}
return -1;
}
int TC_BitMap::BitMap::load5file(const string &sFile)
{
FILE *fp = fopen(sFile.c_str(), "rb");
if(fp == NULL)
{
return -1;
}
fseek(fp, 0L, SEEK_END);
size_t fs = ftell(fp);
if(fs != _pHead->_iMemSize)
{
fclose(fp);
return -2;
}
fseek(fp, 0L, SEEK_SET);
size_t iSize = 1024*1024*10;
size_t iLen = 0;
char *pBuffer = new char[iSize];
while(true)
{
int ret = fread(pBuffer, 1, iSize, fp);
if(ret == 0)
{
break;
}
//检查版本
if(iLen == 0)
{
tagBitMapHead *tmp = (tagBitMapHead*)pBuffer;
if(tmp->_cVersion != BM_VERSION)
{
fclose(fp);
delete[] pBuffer;
return -3;
}
if(tmp->_iMemSize != _pHead->_iMemSize)
{
fclose(fp);
delete[] pBuffer;
return -2;
}
}
memcpy((char*)_pHead + iLen, pBuffer, ret);
iLen += ret;
}
fclose(fp);
delete[] pBuffer;
if(iLen != _pHead->_iMemSize)
{
return -2;
}
return 0;
}