192 lines
3.6 KiB
C++
192 lines
3.6 KiB
C++
#ifndef FIXEDSIZEALLOCATOR_H
|
|
#define FIXEDSIZEALLOCATOR_H
|
|
|
|
|
|
/////////////////////////////////////
|
|
// XFixedSizeAllocator
|
|
// created : AGoTH
|
|
// Date : 05/12/01
|
|
//
|
|
// This class os to allocate fixed size object
|
|
// with a constant time allocation and deallocation
|
|
#ifndef _WIN32_WCE
|
|
#include <limits.h>
|
|
|
|
#undef new
|
|
#undef delete
|
|
|
|
#include <new.h>
|
|
#endif
|
|
|
|
#include "XBitArray.h"
|
|
|
|
//
|
|
class XFixedSizeAllocator
|
|
{
|
|
public:
|
|
enum {
|
|
DEFAULT_CHUNK_SIZE = 4096
|
|
};
|
|
|
|
VX_EXPORT XFixedSizeAllocator(const int iBlockSize,const int iPageSize = DEFAULT_CHUNK_SIZE);
|
|
VX_EXPORT ~XFixedSizeAllocator();
|
|
|
|
// return the number of allocated chunks
|
|
int GetChunksCount()
|
|
{
|
|
return m_Chunks.Size();
|
|
}
|
|
|
|
// return the number of allocated chunks
|
|
VX_EXPORT int GetChunksTotalSize();
|
|
|
|
// return the number of allocated chunks
|
|
VX_EXPORT int GetChunksOccupation();
|
|
|
|
template <class T>
|
|
void CallDtor(T* iDummy)
|
|
{
|
|
// we clear all the chunks
|
|
for (Chunks::Iterator it = m_Chunks.Begin(); it != m_Chunks.End(); ++it) {
|
|
it->CallDtor(iDummy,m_BlockSize,m_BlockCount);
|
|
}
|
|
}
|
|
|
|
VX_EXPORT void Clear();
|
|
|
|
VX_EXPORT void* Allocate();
|
|
|
|
VX_EXPORT void Free(void* iP);
|
|
|
|
private:
|
|
class Chunk
|
|
{
|
|
public:
|
|
Chunk() {}
|
|
|
|
void Init(size_t iBlockSize, unsigned int iBlockCount);
|
|
|
|
template <class T>
|
|
void CallDtor(T* iDummy,size_t iBlockSize, unsigned int iBlockCount)
|
|
{
|
|
// everything is clear -> nothing to do
|
|
if (m_BlockAvailables == iBlockCount)
|
|
return;
|
|
|
|
// else we have some cleaning todo
|
|
|
|
if (!m_BlockAvailables) { // we need to clean everything
|
|
|
|
{ // we call the dtor of the used blocks
|
|
for (unsigned int i=0; i<iBlockCount; ++i) {
|
|
|
|
unsigned char* p = m_Data + i*iBlockSize;
|
|
((T*)p)->~T();
|
|
}
|
|
|
|
}
|
|
|
|
} else { // only some are used
|
|
|
|
XBitArray freeBlocks;
|
|
|
|
{ // we mark the objects used
|
|
int freeb = m_FirstAvailableBlock;
|
|
for (unsigned int i=0; i<m_BlockAvailables-1; ++i) {
|
|
|
|
freeBlocks.Set(freeb);
|
|
|
|
unsigned char* p = m_Data + freeb*iBlockSize;
|
|
freeb = *(int*)p;
|
|
}
|
|
freeBlocks.Set(freeb);
|
|
}
|
|
|
|
{ // we call the dtor of the used blocks
|
|
for (unsigned int i=0; i<iBlockCount; ++i) {
|
|
|
|
if (freeBlocks.IsSet(i))
|
|
continue;
|
|
|
|
unsigned char* p = m_Data + i*iBlockSize;
|
|
((T*)p)->~T();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void Destroy();
|
|
|
|
void* Allocate(size_t iBlockSize);
|
|
|
|
void Deallocate(void* iP, size_t iBlockSize);
|
|
|
|
unsigned char* m_Data;
|
|
unsigned int m_FirstAvailableBlock;
|
|
unsigned int m_BlockAvailables;
|
|
unsigned int m_BlockCount;
|
|
};
|
|
|
|
// types
|
|
typedef XArray<Chunk> Chunks;
|
|
|
|
// function to find the chunk containing the ptr
|
|
Chunk* FindChunk(void* iP);
|
|
|
|
// members
|
|
size_t m_PageSize;
|
|
// Block size
|
|
size_t m_BlockSize;
|
|
// Blocks Count (per Chunk)
|
|
unsigned int m_BlockCount;
|
|
|
|
// the chunks
|
|
Chunks m_Chunks;
|
|
|
|
// Allocating and deallocating chunks
|
|
Chunk* m_AChunk;
|
|
Chunk* m_DChunk;
|
|
|
|
};
|
|
|
|
//
|
|
template <class T>
|
|
class XObjectPool
|
|
{
|
|
public:
|
|
XObjectPool(XBOOL iCallDtor = TRUE):m_Allocator(sizeof(T)),m_CallDtor(iCallDtor) {}
|
|
|
|
T* Allocate()
|
|
{
|
|
return new (m_Allocator.Allocate()) T;
|
|
}
|
|
|
|
void Free(T* iP)
|
|
{
|
|
if (m_CallDtor)
|
|
iP->~T();
|
|
|
|
m_Allocator.Free(iP);
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
if (m_CallDtor)
|
|
m_Allocator.CallDtor((T*)NULL);
|
|
|
|
m_Allocator.Clear();
|
|
}
|
|
|
|
private:
|
|
XFixedSizeAllocator m_Allocator;
|
|
XBOOL m_CallDtor;
|
|
};
|
|
|
|
/*
|
|
#define new (m_setOwner (__FILE__,__LINE__,__FUNCTION__),false) ? NULL : new
|
|
#define delete (m_setOwner (__FILE__,__LINE__,__FUNCTION__),false) ? m_setOwner("",0,"") : delete
|
|
*/
|
|
|
|
#endif // FIXEDSIZEALLOCATOR_H
|