template<class T, int kPageItems>
|
class ItemAlloc
|
{
|
public:
|
struct DataItem
|
{
|
DataItem* next;
|
void* reserve[3];
|
T data[kPageItems];
|
};
|
public:
|
ItemAlloc() :m_pages(0), first(nullptr), freefirst(nullptr), m_items(0), m_maxitems(0)
|
{
|
allocPage();
|
}
|
public:
|
void* allocPage()
|
{
|
m_pages++;
|
DataItem* tmp = (DataItem *)new char[sizeof(DataItem)];
|
|
//initial
|
for (int i = 0; i < kPageItems - 1; i++)
|
{
|
*(void**)(tmp->data+i) = tmp->data+(i + 1);
|
}
|
*(void**)&tmp->data[kPageItems - 1] = freefirst;
|
tmp->next = first;
|
|
first = tmp;
|
freefirst = &tmp->data[0];
|
return tmp;
|
}
|
|
~ItemAlloc()
|
{
|
if (!first)return;
|
DataItem* p = first;
|
DataItem* next = first->next;
|
while (p)
|
{
|
::free(p);
|
if (!next)break;
|
p = next;
|
next = p->next;
|
}
|
}
|
|
T* alloc()
|
{
|
if (!freefirst)allocPage();
|
T* p = freefirst;
|
freefirst = (T*)*(void**)p;
|
m_items++;
|
if(m_items > m_maxitems) m_maxitems++;
|
m_ttlitems++;
|
return p;
|
}
|
void destroy(T* p)
|
{
|
if(p)p->~T();
|
free(p);
|
}
|
void free(void* p )
|
{
|
m_items--;
|
*(void**)p = freefirst;
|
freefirst = (T*)p;
|
}
|
public:
|
DataItem* first;
|
T* freefirst;
|
public:
|
int m_pages;
|
int m_items;
|
int m_maxitems;
|
int m_ttlitems;
|
};
|