一个简单的内存池,源码贡献

头文件

#ifndef MY_MEMPOOL_H
#define MY_MEMPOOL_H


#define MY_MPN_B    namespace my_mempool{
#define MY_MPN_E    }
#define DECLARE_MY_MEMPOOL    using namespace ::my_mempool;

#include <string>
#include <map>
#include <vector>
using namespace ::std;

MY_MPN_B


/**
 * /ingroup my_memorypool
 *    CMPBase,base class ,non copyable.
 *
 * /par requirements
 * win98 or later/n
 * win2k or later/n
 * MFC/n
 *
 * /version 1.0
 * first version
 *
 * /date 2009-06-03
 *
 * /author Jason
 *
 * /par license
 * This code is absolutely free to use and modify. The code is provided "as is" with
 * no expressed or implied warranty. The author accepts no liability if it causes
 * any damage to your computer, causes your pet to fall ill, increases baldness
 * or makes your car start emitting strange noises when you start it up.
 * This code has no bugs, just undocumented features!
 *
 * /todo
 *
 * /bug
 *
 */
class CMPBase
{
private:
    CMPBase(const CMPBase &){}
    CMPBase & operator = (const CMPBase &){return *this;}
public:
    CMPBase(){}
    virtual ~CMPBase() = 0;
protected:
    int round_up(int  size);
public:
    /**
     * 追加一块内存
     * /param size
     *    追加内存的大小
     * /return
     *    返回追加的内存实际大小
     */
    virtual int append(int size) = 0;
   
    virtual void reap(void) = 0;

    /**
     * 计算总空间
     * /param void
     * /return
     */
    virtual int space_(void) = 0;
    /**
     * 计算分配了多少空间
     * /param void
     * /return
     */
    virtual int malloced(void) = 0;
    /**
     * 计算剩余空间
     * /param void
     * /return
     */
    virtual int freememory(void) = 0;

    /**
     * malloc memory,same to stardard c malloc function
     * /param size
     */
    virtual void * malloc(int size) = 0;
    /**
     * free memory
     * /param mp
     */
    virtual void free(void * mp) = 0;

    virtual void dump(const string & file) {};
};



/**
 * /ingroup my_memorypool
 *    class CMapMemoryPool
 *    简单实现
 * /par requirements
 * win98 or later/n
 * win2k or later/n
 * MFC/n
 *
 * /version 1.0
 * first version
 *
 * /date 2009-06-04
 *
 * /author Jason
 *
 * /par license
 * This code is absolutely free to use and modify. The code is provided "as is" with
 * no expressed or implied warranty. The author accepts no liability if it causes
 * any damage to your computer, causes your pet to fall ill, increases baldness
 * or makes your car start emitting strange noises when you start it up.
 * This code has no bugs, just undocumented features!
 *
 * /todo
 *
 * /bug
 *
 */
class CMapMemoryPool : public CMPBase
{
    enum{DEFAULTSIZE = 2 * 1024 * 1024};
    bool initialized;
public:
    CMapMemoryPool();
    CMapMemoryPool(const int & size);
    virtual ~CMapMemoryPool();


    //尽量大些
    virtual int append(int size);
    virtual void reap(void);
    virtual int space_(void){ return malloced() + freememory();}
    virtual int malloced(void);
    virtual int freememory(void);

    virtual void * malloc(int size);
    virtual void free(void * mp);

    virtual void dump(const string & file);

private:
    enum { mbMed = 0x00, mbHeader = 0x01, mbTail = 0x02};
    struct mem_control_block
    {
        int is_available;
        int flag;//mbHeader,mbMed,mbTail
        int size;
        int blockcounter;
    };
    // pointer , memory control block pointer
    map<unsigned int,unsigned int> free_memory;
    map<unsigned int,unsigned int> malloced_memory;

    typedef map<unsigned int,unsigned int> map_type;

    typedef pair<const unsigned int, unsigned int> map_it;

    int count_space(const map_type & m);

    //void realign_right(const unsigned int & pointer);
    //void realign_left(const unsigned int & pointer);

    class CSimpleCount
    {
    public:
        CSimpleCount()
            :count(0)
        {}

        void operator()(const map_it & t)
        {
            mem_control_block * p = (mem_control_block *)(t.second);
            if(p)
                count += p->size;
        }

        int Count(void)
        {
            return count;
        }
    private:
        int count;
    };

    struct temZone
    {
        void * buf;
        int size;

        temZone()
            :buf(0),size(0)
        {
            ;
        }
        temZone(void * b,int s)
            :buf(b),size(s)
        {
            ;
        }
        temZone(const temZone& t)
            :buf(t.buf),size(t.size)
        {
            ;
        }
        temZone & operator = (const temZone &t)
        {
            buf = t.buf;
            size = t.size;
            return *this;
        }
    };
    vector<temZone> _blocks;

    int blockcounter;
};




/**
 * /ingroup my_memorypool
 *    CGeneralMemoryPool,提供线程安全的实现
 *
 * /par requirements
 * win98 or later/n
 * win2k or later/n
 * MFC/n
 *
 * /version 1.0
 * first version
 *
 * /date 2009-06-03
 *
 * /author Jason
 *
 * /par license
 * This code is absolutely free to use and modify. The code is provided "as is" with
 * no expressed or implied warranty. The author accepts no liability if it causes
 * any damage to your computer, causes your pet to fall ill, increases baldness
 * or makes your car start emitting strange noises when you start it up.
 * This code has no bugs, just undocumented features!
 *
 * /todo
 *
 * /bug
 *
 */
template<class MUTEX__,class MPINSTANCE>
class CGeneralMemoryPool : public CMPBase
{
    class CSimGuard
    {
    public:
        CSimGuard(MUTEX__ & l)
            :lk(l)
        {
            lk.acquire();
        }
        ~CSimGuard(void)
        {
            lk.release();
        }
    private:
        MUTEX__ & lk;
    };
public:
    CGeneralMemoryPool()
    {
        mp_ins = new MPINSTANCE;
    }
    CGeneralMemoryPool(int size)
    {
        mp_ins = new MPINSTANCE(size);
    }
    virtual ~CGeneralMemoryPool(void)
    {
        delete mp_ins;
    }

    virtual int append(int size)
    {
        CSimGuard b(lock__);
        return mp_ins->append(size);
    }
    virtual void reap(void)
    {
        CSimGuard b(lock__);
        mp_ins->reap();
    }
    virtual int space_(void)
    {
        CSimGuard b(lock__);
        return mp_ins->space_();
    }
    virtual int malloced(void)
    {
        CSimGuard b(lock__);
        return mp_ins->malloced();
    }
    virtual int freememory(void)
    {
        CSimGuard b(lock__);
        return mp_ins->freememory();
    }
    virtual void * malloc(int size)
    {
        CSimGuard b(lock__);
        return mp_ins->malloc(size);
    }
    virtual void free(void * mp)
    {
        CSimGuard b(lock__);
        mp_ins->free(mp);
    }
    virtual void dump(const string & file)
    {
        CSimGuard b(lock__);
        mp_ins->dump(file);
    }


private:
    CGeneralMemoryPool(const CGeneralMemoryPool &){}
    CGeneralMemoryPool & operator = (const CGeneralMemoryPool & t){return *this;}

    MUTEX__ lock__;

    MPINSTANCE * mp_ins;

};


/**
 * /ingroup my_memorypool
 *    CObjectPool 提供基于内存池的对象级别的内存管理接口
 *
 * /par requirements
 * win98 or later/n
 * win2k or later/n
 * MFC/n
 *
 * /version 1.0
 * first version
 *
 * /date 2009-06-05
 *
 * /author Jason
 *
 * /par license
 * This code is absolutely free to use and modify. The code is provided "as is" with
 * no expressed or implied warranty. The author accepts no liability if it causes
 * any damage to your computer, causes your pet to fall ill, increases baldness
 * or makes your car start emitting strange noises when you start it up.
 * This code has no bugs, just undocumented features!
 *
 * /todo
 *
 * /bug
 *
 */
template<class _ACEMutex,class MPINSTANCE>
class CObjectPool : public CGeneralMemoryPool<_ACEMutex,MPINSTANCE>
{
    typedef CGeneralMemoryPool<_ACEMutex,MPINSTANCE> supper;
public:
    //这个定义应该会屏蔽超类的定义
    template<class T>
    T* malloc(/*int size*/T*& p)
    {
        void* obj = supper::malloc(sizeof(T)/*size*/);
        ::new (obj) T(/* not args */); // 进行默认构造
        p = (T*)obj;
        return /*(T*)obj*/p;
    }

    // 释放对象
    template<class T>
    void free(T* obj)
    {
        if (obj != 0)
        {
            obj->~T();
            supper::free(obj);
        }
    }
};

MY_MPN_E // namespace my_mempool


#endif /*MY_MEMBLOCK_H*/

cpp文件

#include <stdlib.h>
#include <algorithm>
#include <fstream>

#include "MemPool.h"


MY_MPN_B


CMPBase::~CMPBase()
{
    ;
}
int CMPBase::round_up(int  size)
{
     return (( size + 7) &~ 7);// 按8字节对齐
}


CMapMemoryPool::CMapMemoryPool()
:blockcounter(1),initialized(false)
{
    append(DEFAULTSIZE);
}
CMapMemoryPool::CMapMemoryPool(const int & size)
:blockcounter(1),initialized(false)
{
    append(size);
}
CMapMemoryPool::~CMapMemoryPool()
{
    reap();
}


int CMapMemoryPool::append(int size)
{
    if(size < 1024 * 10)
    {
        size = 1024 * 10;
    }
    size = round_up(size);

    char * p = (char*)::malloc(size);
    if(!p)
        return -1;

    ::memset(p,0,size);

    _blocks.push_back(temZone(p,size));

    mem_control_block * pMCB = (mem_control_block *)p;

    pMCB->flag = mbHeader | mbTail;
    pMCB->is_available = 1;
    pMCB->blockcounter = 0;
    pMCB->size = size;
    pMCB->blockcounter = blockcounter++;

    unsigned int v2,v1;
    v2 = (unsigned int)pMCB;
    v1 = (unsigned int)++pMCB;
    pair<map_type::iterator, bool> r ;
    r = free_memory.insert(make_pair(v1,v2));
    if(r.second)
    {
        initialized = true;
        return 0;
    }

    ::free(p);

    return -1;
}

void CMapMemoryPool::reap(void)
{
    initialized = false;
    for(vector<temZone>::iterator i = _blocks.begin(); i != _blocks.end() ; ++i)
    {
        if(i->buf)
            ::free(i->buf);
    }
    _blocks.clear();
}

int CMapMemoryPool::count_space(const map_type & m)
{
    if(!initialized)
        return -1;
    CSimpleCount counter__;
    for_each(m.begin(),m.end(),counter__);
    return counter__.Count();
}

int CMapMemoryPool::malloced(void)
{
    if(!initialized)
        return -1;
    return count_space(malloced_memory);
}
int CMapMemoryPool::freememory(void)
{
    if(!initialized)
        return -1;
    return count_space(free_memory);
}

void * CMapMemoryPool::malloc(int size)
{
    if(!initialized)
        return NULL;
       
    size = round_up(size);

    mem_control_block * p = NULL, * p1 = NULL;
    map_type::iterator i,i1 = free_memory.end();

    //修改实际内存
    for( i = free_memory.begin(); i != free_memory.end(); ++i)
    {
        p = (mem_control_block *)(i->second);
        if( p && p->size > size )
        {
            if( p->size < size * 2 )
            {
                p->is_available = 0;
                break;
            }

            else// larger ,blocking partition, Jason
            {
                int old_size = p->size;
                p->is_available = 0;

                if(old_size - size < sizeof(mem_control_block))
                {
                    break;
                }

                p->size = size + sizeof(mem_control_block);

                p1 = (mem_control_block*)((char*)p + p->size);
                p1->is_available = 1;
                p1->size = old_size - p->size;
                p1->blockcounter = p->blockcounter;

                if( ( p->flag & mbHeader ) == mbHeader && ( p->flag & mbTail ) == mbTail )
                {
                    p->flag = mbHeader;
                    p1->flag = mbTail;
                }

                else if( ( p->flag & mbTail ) == mbTail ) //尾巴
                {
                    p1->flag = mbTail;
                }

                else //if( ( p->flag | mbHeader ) == 0 ) //头和中间的处理一样
                {
                    p1->flag = mbMed;

                    i1 = ++i;
                    --i;
                    mem_control_block * p3 = (mem_control_block *)(i1->second);

                    if((unsigned int )p1 + p1->size != i1->second ) //不连续
                        break;

                    if(p3->blockcounter == p->blockcounter)// same memory block
                    {
                        p1->size += p3->size;
                        p1->flag = p3->flag;
                    }
                }

                break;
            }
        }//if( p && p->size > size )
    }//for

    //修改表
    if( i != free_memory.end() )
    {
        malloced_memory.insert(*i);

        if(i1 != free_memory.end())
            free_memory.erase(i,i1);
        else
            free_memory.erase(i);

        if(p1)//新块,加入进来了
        {
            char * _p = (char*)(p1+1);
            free_memory.insert(make_pair((unsigned int)_p,(unsigned int)p1));
        }

        return (void*)(++p);
    }

    return NULL;
}

void CMapMemoryPool::free(void * mp)
{
    if(!initialized)
        return ;
       
    mem_control_block * p = NULL, * p1 = NULL;
    map_type::iterator i;
    unsigned int k = (unsigned int)mp;
    i = malloced_memory.find(k);
    if(i != malloced_memory.end())
    {
        p = (mem_control_block *)i->second;
        malloced_memory.erase(i); // i 无效了

        p->is_available = 1;

        map_type::iterator previ,nexti;
        unsigned int _pos,pos_;
        map_type::iterator _i = free_memory.end(), i_ = free_memory.end(), it;
       
        pos_ = (unsigned int)p + p->size + sizeof(mem_control_block);
        _pos = 0;

        for( it = free_memory.begin(); it != free_memory.end() ; ++it)
        {
            p1 = (mem_control_block *)it->second;
           
            if(p1->blockcounter != p->blockcounter)
                continue;

            if( (unsigned) p1 + p1->size == (unsigned)p )//正好是前面的
            {
                _i = it;
            }
            else if( (unsigned) p1 == (unsigned)p + p->size )//正好是后面的
            {
                i_ = it;
                break;
            }
            else if((unsigned) p1 /*+ p1->size*/ > (unsigned)p + p->size )
                break;
        }

        if( _i == free_memory.end() && i_ == free_memory.end() )//没有找到邻接点
        {
            free_memory.insert( make_pair( (unsigned int) p + sizeof(mem_control_block) ,(unsigned int)p ) );
        }
        else if( _i != free_memory.end() && i_ != free_memory.end() ) //前驱后继都有
        {
            mem_control_block * _p, *p_;
            _p = (mem_control_block *)_i->second;
            p_ = (mem_control_block *)i_->second;

            _p->size += p->size + p_->size;
            if(p_->flag == mbTail)
                _p->flag |= p_->flag;

            free_memory.erase(_i,i_);
            free_memory.insert( make_pair( (unsigned int) _p + sizeof(mem_control_block) ,(unsigned int)_p ) );
        }
        else if( _i != free_memory.end() )//有前驱点
        {
            p1 = (mem_control_block *)_i->second;
            if(p->flag == mbTail)
                p1->flag |= p->flag;
            p1->size += p->size;

            free_memory.erase(_i);
            free_memory.insert( make_pair( (unsigned int) p1 + sizeof(mem_control_block) ,(unsigned int)p1 ) );
        }
        else if( i_ != free_memory.end() )//有后继点
        {
            p1 = (mem_control_block *)i_->second;
            if(p1->flag == mbTail)
                p->flag |= p1->flag;
            p->size += p1->size;

            free_memory.erase(i_);
            free_memory.insert( make_pair( (unsigned int) p + sizeof(mem_control_block) ,(unsigned int)p ) );
        }
    }
}

void CMapMemoryPool::dump(const string & file)
{
    if(!initialized)
        return ;
       
    fstream fs;
    fs.open(file.c_str(),/*ios::oct |*/ ios_base::out | ios::binary | ios::ate | ios::app);

    if(!fs.bad())
    {
        for( vector<temZone>::iterator i = _blocks.begin(); i != _blocks.end() ; ++i )
        {
            fs.write((const char *)i->buf,i->size);
        }

        fs.close();
    }
}


MY_MPN_E



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值