无锁单线程内存池

来源:互联网 发布:keras tensorflow关系 编辑:程序博客网 时间:2024/06/05 10:16
#ifndef _INCLUDE_FIXLENMEMPOOLNOLOCK_H_
#define _INCLUDE_FIXLENMEMPOOLNOLOCK_H_
#include "log.h"
#include <string>
namespace XUANXUAN
{
//无锁缓存 单线程使用
class CFixLenMemPoolNoLock
{
public:
    struct TBigerItem
    {
        TBigerItem(unsigned int nMemLen)
            :m_pNextItem(NULL)
            ,m_nMemLen(nMemLen)
        {

        }
        TBigerItem* m_pNextItem;
        const unsigned int m_nMemLen;
        char m_pMemHead[1];
    };
    struct TSmallItem
    {
        TSmallItem* m_pNextItem;
    };
    CFixLenMemPoolNoLock(int nFixLen)
        :m_nSmallItemLen(nFixLen>sizeof(TSmallItem)?nFixLen:sizeof(TSmallItem))
    {
        m_nTotalMemLen = 0;
        m_nBigItemNum = 0;
        m_pBigHead = NULL;
        m_pBigTail = NULL;
        m_pSmlHead = NULL;
        m_pSmlTail = NULL;
        m_nGetNum = 0;
        m_nPutNum = 0;
        static int s_PoolID = 0;
        char pName[64];
        sprintf(pName,"pool_%02d<%04u>",s_PoolID++,m_nSmallItemLen);
        m_strName = pName;
    }
    void SetPoolName(const char* pName)
    {
        m_strName = pName;
    }
    char* GetCacheMem(int nRealLen)
    {
        return _GetCacheMem(nRealLen);    
    }
    void PutCacheMem(char* &pMem,int nRealLen)
    {
        _PutCacheMem(pMem,nRealLen);
    }
    unsigned int GetMemInfo(string& strMemInfo)
    {
        char memBuffer[128];
        sprintf(memBuffer,"<%06u> sumMemLen=%-9u totalNum=%-6u  useNum=%-6u\n",m_nSmallItemLen,m_nTotalMemLen,m_nPutNum+m_nGetNum,m_nPutNum);
        strMemInfo = memBuffer;
        return m_nTotalMemLen;
    }
    void ClearMem()
    {
        if (m_nPutNum==0)
        {
            m_pSmlHead = NULL;
            m_pSmlTail = NULL;
            m_nPutNum = 0;
            m_nGetNum = 0;
            m_nTotalMemLen = 0;
            m_nBigItemNum = 0;
            while(m_pBigHead)
            {
                char* pFreeMem = (char*)m_pBigHead;
                m_pBigHead = m_pBigHead->m_pNextItem;
                delete[] pFreeMem;
            }
            m_pBigHead = NULL;
            m_pBigTail = NULL;
        }
    }
private:
    char* _GetCacheMem(int nRealLen)
    {
        LOG(LOG_DEBUG5,"%s nBigNum=%u  canGetNum=%u  canPutNum=%u nrealLen=%u",m_strName.c_str(),m_nBigItemNum,m_nGetNum,m_nPutNum,nRealLen);
        if (NULL == m_pSmlHead)
        {
            _newsmallitem();
        }
        return _popfront_proxy();
    }
    void _PutCacheMem(char* &pMem,int nRealLen)
    {
        LOG(LOG_DEBUG5,"%s nBigNum=%u  canGetNum=%u  canPutNum=%u nrealLen=%u",m_strName.c_str(),m_nBigItemNum,m_nGetNum,m_nPutNum,nRealLen);
        _pushback_proxy((TSmallItem*)pMem);
        pMem = NULL;
    }
private:
    void _newsmallitem()
    {
        TBigerItem* pNewBigerItem = NULL;
        _getbigeritem(pNewBigerItem);
        for(unsigned int i=0;i<pNewBigerItem->m_nMemLen/m_nSmallItemLen;++i)
        {
            TSmallItem* pNewSmallItem = (TSmallItem*)(pNewBigerItem->m_pMemHead+i*m_nSmallItemLen);
            _pushback(pNewSmallItem);
        }
    }
    void _getbigeritem(TBigerItem*& refBigerItem)
    {
        m_nBigItemNum++;
        unsigned int nBigItemLen = sizeof(TBigerItem);
        if (m_nSmallItemLen>=512)
        {
            nBigItemLen += 32*m_nSmallItemLen;
        }
        else
        {
            nBigItemLen += 512*m_nSmallItemLen;
        }
        m_nTotalMemLen += nBigItemLen;
        //LOG(LOG_CRITICAL,"allocbuff size=%u",nBigItemLen);
        refBigerItem = new(new char[nBigItemLen]) TBigerItem(nBigItemLen-sizeof(TBigerItem));
        refBigerItem->m_pNextItem = NULL;
        if (m_pBigTail)
        {
            m_pBigTail->m_pNextItem = refBigerItem;
        }
        else
        {
            m_pBigHead = refBigerItem;
        }
        m_pBigTail = refBigerItem;
    }
    char* _popfront_proxy()
    {
        ++m_nPutNum;
        TSmallItem* pSmallItem = NULL;
        _popfront(pSmallItem);
        return (char*)pSmallItem;
    }
    void _pushback_proxy(TSmallItem* pMemItem)
    {
        --m_nPutNum;
        _pushback(pMemItem);
    }
private:
    void _popfront(TSmallItem*& pMemItem)
    {
        pMemItem = NULL;
        if (m_pSmlHead)
        {
            --m_nGetNum;
            pMemItem = m_pSmlHead;
            if (m_pSmlTail == m_pSmlHead)
            {   //最后一块
                m_pSmlHead = NULL;
                m_pSmlTail = NULL;
            }
            else
            {
                m_pSmlHead = m_pSmlHead->m_pNextItem;
            }
            pMemItem->m_pNextItem = NULL;
        }
    }
    void _pushback(TSmallItem*& pMemItem)
    {
        ++m_nGetNum;
        if (m_pSmlTail)
        {
            m_pSmlTail->m_pNextItem = pMemItem;
        }
        else
        {
            m_pSmlHead = pMemItem;
        }
        m_pSmlTail = pMemItem;

        pMemItem->m_pNextItem = NULL;
        pMemItem = NULL;
    }
protected:
    string m_strName;                    //名称
    const unsigned int m_nSmallItemLen; //小块内存大小

    TBigerItem* m_pBigHead;
    TBigerItem* m_pBigTail;
    unsigned int m_nBigItemNum;  //大缓存块数目
    unsigned int m_nTotalMemLen; //总内存大小

    unsigned int m_nGetNum;    //可申请数目
    unsigned int m_nPutNum; //可释放数目
    TSmallItem* m_pSmlHead;
    TSmallItem* m_pSmlTail;
};
}

#endif





原创粉丝点击