// [7/11/2007 Nextome] #pragma once #include #include #include #include "NxSyncObject.h" template class NxMemPool { public: NxMemPool() : m_pReserveData(NULL), m_nReserveSize(0), m_nUsedReserveSize(0), m_nInitCapacity(0), m_nTotalAllocatedSize(0) { NxGuard Sync(m_CS); if ( RESERVE_SIZE > 0 ) { Reserve( RESERVE_SIZE ); } } virtual ~NxMemPool() { NxGuard Sync(m_CS); Destroy(); } // ¿¹¾à°ø°£À» ÇÒ´çÇÑ´Ù. void Reserve(int nSize) { NxGuard Sync(m_CS); m_nUsedReserveSize = 0; m_nReserveSize = nSize; if ( m_pReserveData ) { delete[] m_pReserveData; m_pReserveData = NULL; } if ( m_nReserveSize > 0 ) { m_pReserveData = new BYTE[sizeof(_T)*m_nReserveSize]; } } void InitCapacity(UINT nCapacity) { NxGuard Sync(m_CS); m_nInitCapacity = nCapacity; m_AllocateData.reserve(m_nInitCapacity); m_FreeData.reserve(m_nInitCapacity); } // ¿¹¾à°ø°£ Á¦°Å void Destroy() { NxGuard Sync(m_CS); if ( m_pReserveData ) { delete[] m_pReserveData; m_pReserveData = NULL; } m_nUsedReserveSize = 0; m_nReserveSize = 0; std::for_each(m_AllocateData.begin(), m_AllocateData.end(), __DeleteAllocatedData ); m_AllocateData.clear(); m_FreeData.clear(); } _T* Alloc() { NxGuard Sync(m_CS); ++m_nTotalAllocatedSize; _T* pData = NULL; if ( m_FreeData.empty() ) { // ¿¹¾à°ø°£¿¡ ³²¾ÆÀÖ´Ù¸é if ( m_nUsedReserveSize < m_nReserveSize ) { pData = ((_T*)m_pReserveData) + (m_nUsedReserveSize++); } // ¾ø´Ù¸é »ý¼ºÇؼ­ ÁØ´Ù. else { pData = __AllocateData(); m_AllocateData.push_back(pData); } return pData; } pData = m_FreeData.back(); m_FreeData.pop_back(); return pData; } inline void Free(_T* pData) { NxGuard Sync(m_CS); --m_nTotalAllocatedSize; m_FreeData.push_back(pData); } inline DWORD GetAllocatedCount() { NxGuard Sync(m_CS); return m_nTotalAllocatedSize; } private: static _T* __AllocateData() { return (_T*)::operator new(sizeof(_T)); } static void __DeleteAllocatedData(_T* pData) { ::operator delete(pData); } private: // ¹Ì¸® ÇÒ´çÇÑ °ø°£ BYTE* m_pReserveData; // Ãß°¡ ÇÒ´çºÐ std::list<_T*> m_AllocateData; std::vector<_T*> m_FreeData; // ¿¹¾à°ø°£ Å©±â DWORD m_nReserveSize; // »ç¿ëÇÑ ¿¹¾à°ø°£ Å©±â DWORD m_nUsedReserveSize; // Ãß°¡ ÇÒ´çºÐÀ» À§ÇÑ ¿¹¾à°ø°£ÃʱâÈ­ Å©±â..-_- DWORD m_nInitCapacity; // Àüü Alloc °¹¼ö DWORD m_nTotalAllocatedSize; // ¸ÖƼ¾²·¹µå ¶ô NxSyncObject m_CS; }; template < class _T, int RESERVE_SIZE = 0 > class NxPooled_Object { typedef NxMemPool<_T, RESERVE_SIZE> SELF_TYPE; public: NxPooled_Object() { } virtual ~NxPooled_Object() { } static _T* Alloc() { return ms_Pool.Alloc(); } static void Free(_T* pData) { ms_Pool.Free(pData); } static SELF_TYPE& GetSharedPool() { return ms_Pool; } protected: static SELF_TYPE ms_Pool; }; template NxMemPool NxPooled_Object::ms_Pool;