tars源码分析之2

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值