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;
- }