Files
mir_server/sdk/srvlib/include/ObjectAllocator.hpp

178 lines
4.9 KiB
C++
Raw Normal View History

2025-01-09 17:45:40 +08:00
#pragma once
/***********************************************************************
使
线
************************************************************************/
#include "ObjectAllocStat.hpp"
#include "Platform.h"
template <typename T>
class CObjectAllocator : public CObjectAllocatorStat
{
public:
//#ifdef _ENABLE_OBJ_COUNT_STATICS_
typedef CObjectAllocatorStat Inherited;
//#endif
//内存块描述结构,用于查询内存块信息
struct DataBlockDesc
{
const char* lpBaseAddress;//内存块指针地址
size_t dwBlockSize; //内存块大小
};
private:
//内存块链表节点
struct DataBlock
{
T* pFreePtr; //指向空闲的对象
T* pEndPtr; //指向对象内存块的结束
DataBlock* pPrev;
} *m_pDataBlock;
public:
enum {
AllocObjectCountOneTime = 1024
};
//申请属性指针
T* allocObjects(const INT_PTR nCount = 1)
{
T* result;
DataBlock *pBlock = m_pDataBlock;
//尝试从当前内存块中申请nCount的对象如果内存块中没有足够的对象则向之前的内存块中查找是否具有足够的空闲对象
if ( !pBlock || pBlock->pEndPtr - pBlock->pFreePtr < nCount )
{
//向之前的内存块中查找是否具有足够的空闲对象
while (pBlock && (pBlock = pBlock->pPrev))
{
if ( pBlock->pEndPtr - pBlock->pFreePtr >= nCount )
break;
}
//如果所有内存块中都没有足够的对象则申请新内存块
if ( pBlock == NULL )
{
INT_PTR nAllocCount = __max(nCount, AllocObjectCountOneTime);
pBlock = (DataBlock*)malloc(sizeof(DataBlock) + sizeof(T) * nAllocCount);
memset(pBlock, 0, sizeof(DataBlock) + sizeof(T) * nAllocCount);
//#ifdef _ENABLE_OBJ_COUNT_STATICS_
m_nAllocObjNum += nAllocCount;
//#endif
pBlock->pFreePtr = (T*)(pBlock + 1);
pBlock->pEndPtr = pBlock->pFreePtr + nAllocCount;
pBlock->pPrev = m_pDataBlock;
m_pDataBlock = pBlock;
}
}
//返回对象指针
result = pBlock->pFreePtr;
pBlock->pFreePtr += nCount;
//#ifdef _ENABLE_OBJ_COUNT_STATICS_
m_nUsedObjNum += nCount;
//#endif
return result;
}
//获取内存块数量
inline INT_PTR blockCount() const
{
INT_PTR result = 0;
DataBlock *pBlock = m_pDataBlock;
while (pBlock)
{
result++;
pBlock = pBlock->pPrev;
}
return result;
}
/*
* Comments:
* Param LPCVOID lpEnumKey: NULL
* Param DataBlockDesc & desc:
* @Return LPCVOID: key指针便NULL则表示枚举结束
*
*
*
* -------------------------------------------------
* LPCVOID lpEnumKey = NULL;
* CObjectAllocator<T>::DataBlockDesc desc;
* while (lpEnumKey = allocator.enumBlockDesc(lpEnumKey, desc))
* {
* printf("Memory Block Info { Address = %X, Size = %u }",
* desc.lpBaseAddress, desc.dwBlockSize);
* }
* --------------------------------------------------------------
*/
inline LPCVOID enumBlockDesc(LPCVOID lpEnumKey, DataBlockDesc &desc) const
{
DataBlock *pBlock = (DataBlock*)lpEnumKey;
if (!pBlock)
pBlock = m_pDataBlock;
else pBlock = pBlock->pPrev;
if (pBlock)
{
desc.lpBaseAddress = ((const char*)pBlock) + sizeof(*pBlock);
desc.dwBlockSize = pBlock->pEndPtr - desc.lpBaseAddress;
return pBlock;
}
return NULL;
}
//#ifdef _ENABLE_OBJ_COUNT_STATICS_
CObjectAllocator(LPCTSTR lpszDesc = NULL) : Inherited(sizeof(T), CObjectAllocatorStat::enAT_ObjectAlloc, lpszDesc)
{
m_pDataBlock = NULL;
}
/*
#else
CObjectAllocator(LPCTSTR lpszDesc = NULL)
{
m_pDataBlock = NULL;
}
#endif
*/
~CObjectAllocator()
{
DataBlock *pBlock, *pPrev;
pBlock = m_pDataBlock;
while (pBlock)
{
pPrev = pBlock->pPrev;
free(pBlock);
pBlock = pPrev;
}
m_pDataBlock = NULL;
}
inline CObjectAllocator& operator = (const CObjectAllocator &rhs)
{
//#ifdef _ENABLE_OBJ_COUNT_STATICS_
Inherited::operator=(rhs);
//#endif
m_pDataBlock = rhs.m_pDataBlock;
//#ifdef _ENABLE_OBJ_COUNT_STATICS_
((CObjectAllocatorStat*)(&rhs))->removeFromStat();
Inherited::addToStat();
//#endif
return *this;
}
private:
CObjectAllocator(const CObjectAllocator &rhs);
};