針對(duì)上篇文章《
基于ACE實(shí)現(xiàn)的一個(gè)內(nèi)存池 》,今天我進(jìn)行了改版,實(shí)之更加方便和合理,代碼如下:
// MemPoolT.h

/**//**
* @date 2007.10.25
* @author PeakGao <peakgao163@163.com>
*/
#ifndef OM_MEMPOOLT_H
#define OM_MEMPOOLT_H

#include <assert.h>
#include <ace/guard_t.h>
#include <ace/global_macros.h>


namespace om
{


/**//**
緩沖池

緩存池采取2維內(nèi)存緩沖機(jī)制,每次new出一個(gè)緩沖鏈,每個(gè)緩沖鏈為
<GrowBlockCount>個(gè)大小為<BlockSize>的內(nèi)存塊,緩沖鏈之間建立鏈表關(guān)
系。

優(yōu)點(diǎn):
1、緩沖池大小由小變大,動(dòng)態(tài)增長,不是一開始就分配一個(gè)超大的內(nèi)
存,真正按需分配;
2、不存在realloc,緩沖地址固定不變;
3、支持FreeList,高效;

缺點(diǎn):
1、分配的對(duì)象在長時(shí)間不用時(shí)沒有實(shí)現(xiàn)智能釋放,以后有需要再改

要求:
1、每個(gè)塊的大小必須大于等于sizeof(Node),32位系統(tǒng)上面是4字節(jié)

示例:
@code
class MyObj
{
public:
MyObj()
{
std_out<<ACE_TEXT("MyObj::MyObj()")<<std_endl;
}
~MyObj()
{
std_out<<ACE_TEXT("MyObj::~MyObj()")<<std_endl;
}
void foo()
{
std_out<<ACE_TEXT("MyObj::foo()")<<std_endl;
}
int dummy;
};

void test()
{
using namespace om;
typedef CachePoolWithLock<ACE_Lock_Adapter<ACE_SYNCH_MUTEX> > CachePool_Lock;

CachePool p1;
p1.create(1024, 256);
void* pp1 = p1.alloc();
p1.free(pp1);
p1.clear();

CachePool_Lock p2(7, 256);
void* pp2 = p2.alloc();
p2.free(pp2);
p2.clear();


ObjectPool<MyObj, CachePool_Lock> pool(128);
MyObj* o = pool.alloc();
o->foo();
pool.free(o);
pool.clear();
}
@endcode
*/

#define BYTE_ALIGN_8 /// 是否支持塊尺寸8字節(jié)對(duì)齊的開關(guān)宏



/**//**
緩存池
這里只實(shí)現(xiàn)邏輯,不考慮線程安全,線程安全的版本見下面的CachePoolWithLock模版
*/
class CachePool

{
protected:


/**//// 緩沖鏈: Head + cache1 + cache2 + cacheN (N=BlockCount)
struct Chain

{
Chain* _Next;


void* data()
{ return this + 1; }

inline static Chain* create(Chain*& head, size_t blockSize, size_t blockCount)

{
#if defined(BYTE_ALIGN_8)
blockSize = blockSize ? ((blockSize + 7) & ~7) : 8; // 8字節(jié)對(duì)齊
#endif
Chain* p = (Chain*) new char[sizeof(Chain) + blockCount * blockSize];

p->_Next = head;
return head = p;
}

void free()

{
Chain* p = this;
while (p)

{
char* buf = (char*)p;
Chain* next = p->_Next;
delete[] buf;
p = next;
}
}
};



/**//// 空閑對(duì)象節(jié)點(diǎn),僅僅在空閑對(duì)象中有效
struct Node

{
Node* _Next;
};



size_t _BlockSize; /**//// 數(shù)據(jù)塊的字節(jié)大小

size_t _GrowBlockCount; /**//// 每次連續(xù)分配的塊數(shù)

Chain* _ChainList; /**//// 每次分配的緩沖鏈

Node* _FreeNode; /**//// 當(dāng)前空閑節(jié)點(diǎn)

public:

/**//// 默認(rèn)構(gòu)造,注意必須調(diào)用create方法初始化參數(shù)
CachePool()
: _BlockSize(0), _GrowBlockCount(0), _ChainList(0), _FreeNode(0)

{
}

CachePool(size_t blockSize, size_t growBlockCount)
: _ChainList(0), _FreeNode(0)

{
create(blockSize, growBlockCount);
}

~CachePool()

{
clear();
}


/**//// 清除所有的內(nèi)存空間
void clear()

{
if (_ChainList)

{
_ChainList->free();
_ChainList = 0;
_FreeNode = 0;
}
}


/**//// 初始化參數(shù)
void create(size_t blockSize, size_t growBlockCount)

{
_BlockSize = blockSize;
_GrowBlockCount = growBlockCount;

assert(_GrowBlockCount >= 1);
assert(_BlockSize >= sizeof(Node));
}


/**//// 獲取塊的大小
size_t getBlockSize() const

{
return _BlockSize;
}


/**//// 獲取連續(xù)分配的塊的數(shù)目
size_t getGrowBlockCount() const

{
return _GrowBlockCount;
}


/**//// 分配一個(gè)塊內(nèi)存
void* alloc()

{
assert(_GrowBlockCount >= 1);
assert(_BlockSize >= sizeof(Node));

if (_FreeNode == 0)

{
// 分配另一個(gè)數(shù)據(jù)鏈
Chain* newChain = Chain::create(_ChainList, _BlockSize, _GrowBlockCount);

Node* node = (Node*)newChain->data();

// 定位到最后一個(gè)節(jié)點(diǎn)
(char*&)node += _BlockSize * (_GrowBlockCount - 1);

// 建立連接關(guān)系
for (int i=(int)_GrowBlockCount-1; i>=0; i--, (char*&)node -= _BlockSize)

{
node->_Next = _FreeNode;
_FreeNode = node;
}
}

assert(_FreeNode != 0);

void* block = (void*)_FreeNode;
_FreeNode = _FreeNode->_Next;

return block;
}


/**//// 釋放塊內(nèi)存
void free(void* block)

{
if (block != 0)

{
Node* node = (Node*)block;
node->_Next = _FreeNode;
_FreeNode = node;
}
}
};





/**//**
支持鎖策略的緩存池,目前用的ACE的鎖,可以很方便的改為其他的鎖策略
比如_ACELOCK可以為鎖對(duì)象ACE_Lock_Adapter<ACE_SYNCH_MUTEX>,也可以
直接用互斥體如ACE_SYNCH_NULL_MUTEX
*/
template<class ACELOCK>
class CachePoolWithLock : public CachePool

{
protected:

ACELOCK _Lock; /**//// 鎖

public:
CachePoolWithLock()

{
}

CachePoolWithLock(size_t blockSize, size_t growBlockCount)
: CachePool(blockSize, growBlockCount)

{
}


/**//// 清除所有的內(nèi)存空間
void clear()

{
ACE_GUARD(ACELOCK, ace_mon, _Lock);
CachePool::clear();
}


/**//// 分配一個(gè)塊內(nèi)存
void* alloc()

{
ACE_GUARD_RETURN(ACELOCK, ace_mon, _Lock, NULL);
return CachePool::alloc();
}


/**//// 釋放塊內(nèi)存
void free(void* block)

{
ACE_GUARD(ACELOCK, ace_mon, _Lock);
CachePool::free(block);
}
};


/**//**
對(duì)象池
在緩沖池的基礎(chǔ)上,增加了對(duì)象的構(gòu)造和析構(gòu)為了更好擴(kuò)充,模版參數(shù)直接傳入緩沖池類型,可
以是上面的CachePool、CachePoolWithLock,也可以是用戶自定義的緩沖池,但必須符合調(diào)用規(guī)范
*/
template<class T, class CachePoolStrategy>
class ObjectPool : public CachePoolStrategy

{
protected:
typedef CachePoolStrategy _Base;

public:
ObjectPool()

{
}

ObjectPool(size_t growBlockCount)
: _Base(sizeof(T), growBlockCount)

{
}


/**//// 初始化參數(shù)
void create(size_t growBlockCount)

{
_Base::create(sizeof(T), growBlockCount);
}


/**//// 創(chuàng)建對(duì)象的內(nèi)存空間,但是沒有進(jìn)行構(gòu)造,用戶可以自行進(jìn)行定制的構(gòu)造
T* alloc()

{
void* obj = _Base::alloc();
::new (obj) T(); // 只提供了采用默認(rèn)構(gòu)造的方式
return (T*)obj;
}


/**//// 釋放對(duì)象
void free(T* obj)

{
if (obj != 0)

{
obj->~T();
_Base::free(obj);
}
}
};

} // namespace om

#endif // OM_MEMPOOLT_H