您的位置:首页 > 移动开发 > Objective-C

对象内存池实现

2014-03-25 12:14 288 查看
///
/// Copyright (c) xseekerj 2014,All Rights Reserved.
///

#ifndef _OBJECT_POOL_H_
#define _OBJECT_POOL_H_
#ifndef _POLITE_SZ_ALIGN
#define _POLITE_SZ_ALIGN
#define sz_align(d,a) (((d) + (a - 1)) & ~(a - 1))
#endif
template<typename _Ty, size_t _ElemCount = 1024>
class object_pool
{
typedef struct free_link_node
{
free_link_node* next;
} *free_link;

typedef struct chunk_link_node
{
char             data[sz_align(sizeof(_Ty), sizeof(void*)) * _ElemCount];
chunk_link_node* next;
} *chunk_link;

object_pool(const object_pool&);
void operator= (const object_pool&);

public:
object_pool(void) : _Myhead(nullptr), _Mychunk(nullptr), _Mycount(0)
{
this->_Enlarge();
}

~object_pool(void)
{
this->purge();
}

void cleanup(void)
{
if(this->_Mychunk = nullptr) {
return;
}
free_link_node* prev = nullptr;
chunk_link_node* chunk = this->_Mychunk;
for (; chunk != nullptr; chunk = chunk->next)
{
char* begin     = chunk->data;
char* rbegin    = begin + (_ElemCount - 1) * sz_align(sizeof(_Ty), sizeof(void*));
if(prev != nullptr)
prev->next = reinterpret_cast<free_link>(begin);
for (char* ptr = begin; ptr < rbegin; ptr += sz_align(sizeof(_Ty), sizeof(void*)) )
{
reinterpret_cast<free_link_node*>(ptr)->next = reinterpret_cast<free_link_node*>(ptr + sz_align(sizeof(_Ty), sizeof(void*)));
}
prev = reinterpret_cast <free_link_node*>(rbegin);
}
this->_Myhead = reinterpret_cast<free_link_node*>(this->_Mychunk->data);
this->_Mycount = 0;
}

void purge(void)
{
chunk_link_node* ptr = this->_Mychunk;
while (ptr != nullptr)
{
chunk_link_node* deleting = ptr;
ptr = ptr->next;
free(deleting);
}
_Myhead = nullptr;
_Mychunk = nullptr;
_Mycount = 0;
}

size_t count(void) const
{
return _Mycount;
}

// if the type is not pod, you may be use placement new to call the constructor,
// for example: _Ty* obj = new(pool.get()) _Ty(arg1,arg2,...);
void* get(void)
{
if (nullptr == this->_Myhead)
{
this->_Enlarge();
}
free_link_node* ptr = this->_Myhead;
this->_Myhead = ptr->next;
++_Mycount;
return reinterpret_cast<void*>(ptr);
}
void release(void* _Ptr)
{
( (_Ty*)_Ptr)->~_Ty(); // call the destructor
#ifdef _DEBUG
::memset(_Ptr, 0x00, sizeof(_Ty));
#endif
free_link_node* ptr = reinterpret_cast<free_link_node*>(_Ptr);
ptr->next = this->_Myhead;
this->_Myhead = ptr;
--_Mycount;
}

private:
void _Enlarge(void)
{
static_assert(_ElemCount > 0, "Invalid Element Count");

chunk_link new_chunk  = (chunk_link)malloc(sizeof(chunk_link_node));
#ifdef _DEBUG
::memset(new_chunk, 0x00, sizeof(chunk_link_node));
#endif
new_chunk->next = this->_Mychunk;
this->_Mychunk  = new_chunk;

char* begin     = this->_Mychunk->data;
char* rbegin    = begin + (_ElemCount - 1) * sz_align(sizeof(_Ty), sizeof(void*));

for (char* ptr = begin; ptr < rbegin; ptr += sz_align(sizeof(_Ty), sizeof(void*)))
{
reinterpret_cast<free_link_node*>(ptr)->next = reinterpret_cast<free_link_node*>(ptr + sz_align(sizeof(_Ty), sizeof(void*)));
}

reinterpret_cast <free_link_node*>(rbegin)->next = nullptr;
this->_Myhead = reinterpret_cast<free_link_node*>(begin);
}

private:
free_link     _Myhead;  // link to free head
chunk_link    _Mychunk; // chunk link
size_t        _Mycount; // allocated count
};

#endif









内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ c 内存 object 对象