// MemBand.h: interface for the CMemBand Abstract class. // Memory Pool Management Class version 1.0 // source code created by Min-Wook Kim (taiyo@webzen.co.kr) // 2004-7-26 // //------------------------------------------------------------------- // History. // 2004-3-31 : MemoryPoolTempl class ver 0.1 // 2004-6-18 : MemoryPoolTempl class ver 0.2 // 2004-6-21 : Error Check Byte added ver 0.21 // 2004-7-26 : MemoryPool Framework ver1.0 // 2004-7-27 : Bug Fixed! delete [] m_pQueue; // Be Done // - MemoryPool template class of inherited-method and factory-method // - Multi-thread safety // - Buffer overflow write check // To do // - Analysis of amount used for band //------------------------------------------------------------------- // ////////////////////////////////////////////////////////////////////// #ifndef __MEMBAND_H__ #define __MEMBAND_H__ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0500 #endif #define _PSDK_INSTALLED #include #ifdef _DEBUG #include #define TASSERT(a) assert(a) #define DEBUG_SLICE_SIZE 4 #define DEBUG_SLICE_VALUE 'D' #else #define DEBUG_SLICE_SIZE 0 #endif namespace util { #if 0 template class CMemBand { static CMemBand * m_pHeadBand; static CMemBand * m_pTailBand; static CMemBand * m_pCurBand; static DWORD m_dwObjSize; static DWORD m_dwPoolBasicSize; static DWORD m_dwPoolExtendSize; char * m_pBandBody; DWORD * m_pQueue; DWORD m_dwObjCount; DWORD m_dwMaxBandObjCount; CMemBand * m_pPrev; CMemBand * m_pNext; protected: CMemBand() : m_pPrev(NULL), m_pNext(NULL), m_pBandBody(0), m_pQueue(0), m_dwObjCount(0), m_dwMaxBandObjCount(0) { } virtual ~CMemBand() { } static void * AlloObject() { if( m_pCurBand->m_dwObjCount > 0 ) { return (void *)*(m_pCurBand->m_pQueue + --m_pCurBand->m_dwObjCount); } else { AllocBand(); m_pCurBand = m_pCurBand->m_pNext; return AlloObject(); } } static BOOL FreeObject(void * pObj) { if( m_pCurBand->m_dwObjCount < m_pCurBand->m_dwMaxBandObjCount ) { #ifdef _DEBUG for( int i = 0 ; i < DEBUG_SLICE_SIZE ; ++i ) { if( ((char * )pObj)[m_dwObjSize - DEBUG_SLICE_SIZE + i] != DEBUG_SLICE_VALUE ) return FALSE; } #endif *(m_pCurBand->m_pQueue + m_pCurBand->m_dwObjCount) = (DWORD)pObj; m_pCurBand->m_dwObjCount++; } else { m_pCurBand = m_pCurBand->m_pPrev; return FreeObject(pObj); } return TRUE; } static void InitBand(DWORD dwObjSize, DWORD dwPoolBasicSize, DWORD dwPoolExtendSize) { m_dwObjSize = dwObjSize + DEBUG_SLICE_SIZE; m_dwPoolBasicSize = dwPoolBasicSize; m_dwPoolExtendSize = dwPoolExtendSize; AllocBand(); } static void AllocBand() { CMemBand * pBand = new CMemBand; DWORD dwPoolSize = 0; if( !m_pHeadBand ) { dwPoolSize = m_dwPoolBasicSize; m_pCurBand = m_pHeadBand = m_pTailBand = pBand; } else { dwPoolSize = m_dwPoolExtendSize; m_pTailBand->m_pNext = pBand; pBand->m_pPrev = m_pTailBand; m_pTailBand = pBand; } pBand->m_pBandBody = new char[m_dwObjSize*dwPoolSize]; #ifdef _DEBUG DWORD j = 0; while( j < dwPoolSize ) { memset( &pBand->m_pBandBody[ m_dwObjSize * ( j + 1 ) - DEBUG_SLICE_SIZE ], DEBUG_SLICE_VALUE, DEBUG_SLICE_SIZE ); ++j; } #endif pBand->m_pQueue = new DWORD[dwPoolSize]; DWORD i = 0; while( i < dwPoolSize ) { *(pBand->m_pQueue + i) = (DWORD)(pBand->m_pBandBody + i * m_dwObjSize); ++i; } pBand->m_dwObjCount = dwPoolSize; pBand->m_dwMaxBandObjCount = dwPoolSize; } static void FreeBand() { CMemBand * dp = m_pHeadBand; while(dp) { m_pHeadBand = m_pHeadBand->m_pNext; delete [] dp->m_pBandBody; delete [] dp->m_pQueue; delete dp; dp = m_pHeadBand; } m_pHeadBand = NULL; } }; template CMemBand * CMemBand::m_pHeadBand = NULL; template CMemBand * CMemBand::m_pTailBand = NULL; template CMemBand * CMemBand::m_pCurBand = NULL; template DWORD CMemBand::m_dwObjSize = 0; template DWORD CMemBand::m_dwPoolBasicSize = 0; template DWORD CMemBand::m_dwPoolExtendSize = 0; #endif template class CMemTypeBand { DataType ** ppDataType; DataType * pDeleteArray; DWORD nMaxBandObjectNum; DWORD FreeIdx; public: CMemTypeBand * pPrev; CMemTypeBand * pNext; CMemTypeBand():pPrev(NULL),pNext(NULL){} virtual ~CMemTypeBand() { pPrev=NULL;pNext=NULL; delete [] (ppDataType); delete [] (pDeleteArray); } inline DWORD GetAvailableNumberOfObjects() { return FreeIdx; } inline DWORD GetMaxNumberOfObjects() { return nMaxBandObjectNum; } DataType * GetObject( DWORD dwIdx ) { return &pDeleteArray[dwIdx]; } static CMemTypeBand * AllocBand( CMemTypeBand *& head, DWORD nMaxObject ) { CMemTypeBand* pp = new CMemTypeBand; pp->ppDataType = new DataType*[nMaxObject]; memset(pp->ppDataType, 0, sizeof(DataType*)*nMaxObject); pp->pDeleteArray = new DataType[nMaxObject]; for(DWORD i = 0 ; i < nMaxObject ; i++) { pp->ppDataType[i] = &pp->pDeleteArray[i]; } pp->nMaxBandObjectNum = nMaxObject; pp->FreeIdx = nMaxObject; pp->pNext = head; if(head) head->pPrev = pp; head = pp; return pp; } static void FreeBand( CMemTypeBand * pDelBand ) { //head node one call, all delete; CMemTypeBand * db = pDelBand; while(db) { CMemTypeBand * tmp = db; db = db->pNext; delete tmp; } } DataType * AlloObject() { // TASSERT(FreeIdx-1 >= 0); if(--FreeIdx == -1) { FreeIdx = 0; return NULL; } else return ppDataType[FreeIdx]; } BOOL FreeObject(DataType * data) { // TASSERT(FreeIdx+1 < nMaxNum); if(FreeIdx < nMaxBandObjectNum ) ppDataType[FreeIdx++] = data; else return FALSE; return TRUE; } }; } /// namespace util #endif // __MEMBAND_H__