1
0

Added generic Allocation Pool Interface

This commit is contained in:
Tycho 2014-06-14 19:46:34 +01:00
parent a1520c7a40
commit 94c48febd2
12 changed files with 110 additions and 69 deletions

View File

@ -3,21 +3,31 @@
#include <memory> #include <memory>
template<class T>
class cAllocationPool
{
public:
class cStarvationCallbacks
{
public:
virtual ~cStarvationCallbacks() {}
virtual void OnStartingUsingBuffer() = 0;
virtual void OnStopUsingBuffer() = 0;
virtual void OnBufferEmpty() = 0;
};
virtual ~cAllocationPool() {}
virtual T * Allocate() = 0;
virtual void Free(T * a_ptr) = 0;
};
template<class T, size_t NumElementsInReserve> template<class T, size_t NumElementsInReserve>
class cAllocationPool class cListAllocationPool : public cAllocationPool<T>
{ {
public: public:
class cStarvationCallbacks
{
public:
virtual ~cStarvationCallbacks() {}
virtual void OnStartingUsingBuffer() = 0;
virtual void OnStopUsingBuffer() = 0;
virtual void OnBufferEmpty() = 0;
};
cAllocationPool(std::auto_ptr<cStarvationCallbacks> a_Callbacks) : cListAllocationPool(std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> a_Callbacks) :
m_Callbacks(a_Callbacks) m_Callbacks(a_Callbacks)
{ {
for (size_t i = 0; i < NumElementsInReserve; i++) for (size_t i = 0; i < NumElementsInReserve; i++)
@ -32,7 +42,7 @@ class cAllocationPool
} }
} }
~cAllocationPool() virtual ~cListAllocationPool()
{ {
while (!m_FreeList.empty()) while (!m_FreeList.empty())
{ {
@ -41,7 +51,7 @@ class cAllocationPool
} }
} }
T * Allocate() virtual T * Allocate() override
{ {
if (m_FreeList.size() <= NumElementsInReserve) if (m_FreeList.size() <= NumElementsInReserve)
{ {
@ -66,15 +76,15 @@ class cAllocationPool
m_FreeList.pop_front(); m_FreeList.pop_front();
return ret; return ret;
} }
void Free(T * ptr) virtual void Free(T * a_ptr) override
{ {
if (ptr == NULL) if (a_ptr == NULL)
{ {
return; return;
} }
// placement destruct. // placement destruct.
ptr->~T(); a_ptr->~T();
m_FreeList.push_front(ptr); m_FreeList.push_front(a_ptr);
if (m_FreeList.size() == NumElementsInReserve) if (m_FreeList.size() == NumElementsInReserve)
{ {
m_Callbacks->OnStopUsingBuffer(); m_Callbacks->OnStopUsingBuffer();
@ -83,5 +93,5 @@ class cAllocationPool
private: private:
std::list<void *> m_FreeList; std::list<void *> m_FreeList;
std::auto_ptr<cStarvationCallbacks> m_Callbacks; std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> m_Callbacks;
}; };

View File

@ -65,7 +65,7 @@ cChunk::cChunk(
int a_ChunkX, int a_ChunkY, int a_ChunkZ, int a_ChunkX, int a_ChunkY, int a_ChunkZ,
cChunkMap * a_ChunkMap, cWorld * a_World, cChunkMap * a_ChunkMap, cWorld * a_World,
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP,
cAllocationPool<cChunkData::sChunkSection, 1600> & a_Pool cAllocationPool<cChunkData::sChunkSection> & a_Pool
) : ) :
m_IsValid(false), m_IsValid(false),
m_IsLightValid(false), m_IsLightValid(false),

View File

@ -66,7 +66,7 @@ public:
int a_ChunkX, int a_ChunkY, int a_ChunkZ, // Chunk coords int a_ChunkX, int a_ChunkY, int a_ChunkZ, // Chunk coords
cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, // Neighbor chunks cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, // Neighbor chunks
cAllocationPool<cChunkData::sChunkSection, 1600> & a_Pool cAllocationPool<cChunkData::sChunkSection> & a_Pool
); );
cChunk(cChunk & other); cChunk(cChunk & other);
~cChunk(); ~cChunk();

View File

@ -27,7 +27,7 @@ template <typename T> inline bool IsAllValue(const T * a_Array, size_t a_NumElem
cChunkData::cChunkData(cAllocationPool<cChunkData::sChunkSection, 1600> & a_Pool) : cChunkData::cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool) :
#if __cplusplus < 201103L #if __cplusplus < 201103L
// auto_ptr style interface for memory management // auto_ptr style interface for memory management
m_IsOwner(true), m_IsOwner(true),

View File

@ -37,7 +37,7 @@ public:
struct sChunkSection; struct sChunkSection;
cChunkData(cAllocationPool<cChunkData::sChunkSection, 1600> & a_Pool); cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool);
~cChunkData(); ~cChunkData();
#if __cplusplus < 201103L #if __cplusplus < 201103L
@ -122,7 +122,7 @@ private:
/** Sets the data in the specified section to their default values. */ /** Sets the data in the specified section to their default values. */
void ZeroSection(sChunkSection * a_Section) const; void ZeroSection(sChunkSection * a_Section) const;
cAllocationPool<cChunkData::sChunkSection, 1600> & m_Pool; cAllocationPool<cChunkData::sChunkSection> & m_Pool;
}; };

View File

@ -35,8 +35,14 @@
cChunkMap::cChunkMap(cWorld * a_World ) cChunkMap::cChunkMap(cWorld * a_World )
: m_World( a_World ), : m_World( a_World ),
m_Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks>(new cStarvationCallbacks())) m_Pool(
new cListAllocationPool<cChunkData::sChunkSection, 1600>(
std::auto_ptr<cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks>(
new cStarvationCallbacks())
)
)
{ {
} }
@ -79,7 +85,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ)
} }
// Not found, create new: // Not found, create new:
cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, m_Pool); cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, *m_Pool);
if (Layer == NULL) if (Layer == NULL)
{ {
LOGERROR("cChunkMap: Cannot create new layer, server out of memory?"); LOGERROR("cChunkMap: Cannot create new layer, server out of memory?");
@ -2672,7 +2678,7 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
// cChunkMap::cChunkLayer: // cChunkMap::cChunkLayer:
cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent, cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent,
cAllocationPool<cChunkData::sChunkSection, 1600> & a_Pool) cAllocationPool<cChunkData::sChunkSection> & a_Pool)
: m_LayerX( a_LayerX ) : m_LayerX( a_LayerX )
, m_LayerZ( a_LayerZ ) , m_LayerZ( a_LayerZ )
, m_Parent( a_Parent ) , m_Parent( a_Parent )

View File

@ -352,7 +352,7 @@ private:
{ {
public: public:
cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent, cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent,
cAllocationPool<cChunkData::sChunkSection, 1600> & a_Pool); cAllocationPool<cChunkData::sChunkSection> & a_Pool);
~cChunkLayer(); ~cChunkLayer();
/** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */ /** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */
@ -397,11 +397,11 @@ private:
cChunkMap * m_Parent; cChunkMap * m_Parent;
int m_NumChunksLoaded; int m_NumChunksLoaded;
cAllocationPool<cChunkData::sChunkSection, 1600> & m_Pool; cAllocationPool<cChunkData::sChunkSection> & m_Pool;
}; };
class cStarvationCallbacks class cStarvationCallbacks
: public cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks : public cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks
{ {
virtual void OnStartingUsingBuffer() virtual void OnStartingUsingBuffer()
{ {
@ -447,7 +447,7 @@ private:
/** The cChunkStay descendants that are currently enabled in this chunkmap */ /** The cChunkStay descendants that are currently enabled in this chunkmap */
cChunkStays m_ChunkStays; cChunkStays m_ChunkStays;
cAllocationPool<cChunkData::sChunkSection, 1600> m_Pool; std::auto_ptr<cAllocationPool<cChunkData::sChunkSection>> m_Pool;
cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid
cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate

View File

@ -6,14 +6,19 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
class cStarvationCallbacks class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual void OnStartingUsingBuffer() {} virtual cChunkData::sChunkSection * Allocate()
virtual void OnStopUsingBuffer() {} {
virtual void OnBufferEmpty() {} return new cChunkData::sChunkSection();
}; }
cAllocationPool<cChunkData::sChunkSection, 1600> Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks>(new cStarvationCallbacks()));
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
{ {
// Test first segment // Test first segment

View File

@ -6,14 +6,19 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
class cStarvationCallbacks class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual void OnStartingUsingBuffer() {} virtual cChunkData::sChunkSection * Allocate()
virtual void OnStopUsingBuffer() {} {
virtual void OnBufferEmpty() {} return new cChunkData::sChunkSection();
}; }
cAllocationPool<cChunkData::sChunkSection, 1600> Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks>(new cStarvationCallbacks()));
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
{ {
cChunkData buffer(Pool); cChunkData buffer(Pool);

View File

@ -6,14 +6,19 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
class cStarvationCallbacks class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual void OnStartingUsingBuffer() {} virtual cChunkData::sChunkSection * Allocate()
virtual void OnStopUsingBuffer() {} {
virtual void OnBufferEmpty() {} return new cChunkData::sChunkSection();
}; }
cAllocationPool<cChunkData::sChunkSection, 1600> Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks>(new cStarvationCallbacks()));
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
{ {
cChunkData buffer(Pool); cChunkData buffer(Pool);

View File

@ -17,14 +17,19 @@
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
// Set up a cChunkData with known contents - all blocks 0x01, all metas 0x02: // Set up a cChunkData with known contents - all blocks 0x01, all metas 0x02:
class cStarvationCallbacks class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual void OnStartingUsingBuffer() {} virtual cChunkData::sChunkSection * Allocate()
virtual void OnStopUsingBuffer() {} {
virtual void OnBufferEmpty() {} return new cChunkData::sChunkSection();
}; }
cAllocationPool<cChunkData::sChunkSection, 1600> Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks>(new cStarvationCallbacks()));
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
cChunkData Data(Pool); cChunkData Data(Pool);
cChunkDef::BlockTypes BlockTypes; cChunkDef::BlockTypes BlockTypes;
cChunkDef::BlockNibbles BlockMetas; cChunkDef::BlockNibbles BlockMetas;

View File

@ -4,14 +4,19 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
class cStarvationCallbacks class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks : public cAllocationPool<cChunkData::sChunkSection>
{ {
virtual void OnStartingUsingBuffer() {} virtual cChunkData::sChunkSection * Allocate()
virtual void OnStopUsingBuffer() {} {
virtual void OnBufferEmpty() {} return new cChunkData::sChunkSection();
}; }
cAllocationPool<cChunkData::sChunkSection, 1600> Pool(std::auto_ptr<cAllocationPool<cChunkData::sChunkSection, 1600>::cStarvationCallbacks>(new cStarvationCallbacks()));
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
cChunkData buffer(Pool); cChunkData buffer(Pool);
return 0; return 0;
} }