#ifndef _EXCELSIOR_CACHEMANAGE_H_
#define _EXCELSIOR_CACHEMANAGE_H_
#include <string>
using namespace std;
#include "List.h"
struct TCacheAllocStauts
{
UINT8** pType;
UINT32 start;
UINT32 size;
};
class CacheManage
{
protected:
CacheManage(const CacheManage&){}
public:
/**********************************************************************
* 功 能 : // 构造函数
* 输入参数: // size:初始化分配的内存大小,默认4M
* 输出参数: //
* 返 回 值: //
***********************************************************************/
CacheManage(UINT32 size = 4 * 1024 * 1024){}
~CacheManage()
{}
/**********************************************************************
* 功 能 : // 分配一块内存给pType
* 输入参数: // pType:要申请内存的对象地址,size:要分配的内存大小
* 输出参数: // pType:分配成功不为NULL,否则为NULL
* 返 回 值: // 分配结果,失败返回NULL
***********************************************************************/
UINT8* Alloc(UINT8* &pType, UINT32 size);
/**********************************************************************
* 功 能 : // 收回分配给pType的内存,调用该方法前,需要做相应的清理工作
* 输入参数: // pType:把内存分配给的对象地址
* 输出参数: //
* 返 回 值: //
***********************************************************************/
void Free(UINT8* &pType);
/**********************************************************************
* 功 能 : // 打印缓存信息
* 输入参数: //
* 输出参数: //
* 返 回 值: // 缓存信息
***********************************************************************/
string ToString();
private:
/**********************************************************************
* 功 能 : // 整理零碎内存
* 输入参数: //
* 输出参数: //
* 返 回 值: //
***********************************************************************/
void CollectFreeMemory();
UINT8 *m_pCache; /* 保存一块用来分配的连续内存区域 */
UINT32 m_iPos;
UINT32 m_size;
CNodeList<TCacheAllocStauts> m_stautsList; /* 保存已经分配的状态 */
};
#endif
//程序的实现:
/********************************************************************
Copyright (C) 2007 - All Rights Reserved
创建时间: 2007/11/27 10:41
文件名 : CacheManage.cpp
作者: Fu.Changyou
版本: V1.0
目的: 缓存管理类的实现
函数列表:
修改日志:
<作者> <时间> <版本> <描述>
*********************************************************************/
#include "CacheManage.h"
#include "Exception.h"
/**********************************************************************
* 功 能 : // 构造函数
* 输入参数: // size:初始化分配的内存大小
* 输出参数: //
* 返 回 值: //
***********************************************************************/
CacheManage::CacheManage(UINT32 size /* = 4 * 1024 * 1024 */)
{
if (size <= 0)
{
throw CException("alloc size[%u] error", size);
}
NEW(m_pCache, UINT8[size]);
if (NULL == m_pCache)
{
throw CException("alloc memory error, memory size is %u", size);
}
m_iPos = 0;
m_size = size;
}
CacheManage::~CacheManage()
{
DELETEPTR(m_pCache);
}
/**********************************************************************
* 功 能 : // 分配一块内存给pType
* 输入参数: // pType:要申请内存的对象地址,size:要分配的内存大小
* 输出参数: // pType:分配成功不为NULL,否则为NULL
* 返 回 值: // 分配结果,失败返回NULL
***********************************************************************/
UINT8* CacheManage::Alloc(UINT8* &pType, UINT32 size)
{
/* 申请的大小不能小于等于0 */
if (size <= 0)
{
return NULL;
}
/* 如果内存不够分配,就需要整理零碎内存 */
if (size > m_size - m_iPos)
{
CollectFreeMemory();
/* 如果整理后还是不够的话,就申请失败 */
if (size > m_size - m_iPos)
{
return NULL;
}
}
pType = m_pCache + m_iPos;
/* 保存该信息 */
TCacheAllocStauts stauts;
stauts.pType = &pType;
stauts.start = m_iPos;
stauts.size = size;
m_stautsList.AddTail(stauts);
/* 改变当前位置,以备下次别的模块申请 */
m_iPos += size;
/* 分配内存 */
return pType;
}
/**********************************************************************
* 功 能 : // 收回分配给pType的内存,调用该方法前,需要做相应的清理工作
* 输入参数: // pType:把内存分配给的对象的地址
* 输出参数: //
* 返 回 值: //
***********************************************************************/
void CacheManage::Free(UINT8* &pType)
{
TNode<TCacheAllocStauts> *pNode = m_stautsList.Front();
while (pNode)
{
if (pNode->Value().pType == &pType)
{
int iStart = pNode->Value().start;
int iSize = pNode->Value().size;
/* 从状态信息链表中删除该信息 */
m_stautsList.Remove(pNode);
/* 将该内存置为0 */
memset(m_pCache + iStart, 0, iSize);
break;
}
pNode = m_stautsList.Next();
}
}
/**********************************************************************
* 功 能 : // 打印缓存信息
* 输入参数: //
* 输出参数: //
* 返 回 值: // 缓存信息
***********************************************************************/
string CacheManage::ToString()
{
/* head */
string sTmp = "Cache Informations is:\n"
"Size:";
sTmp += m_size;
sTmp += "\nCurrent Position:";
sTmp += m_iPos;
/* body */
char* pSpace1 = " ";
char* pSpace2 = " ; ";
int iPos = 0;
char sTmp1[64];
char sTmp2[32];
memset(sTmp1, 0, sizeof(sTmp1));
memset(sTmp2, 0, sizeof(sTmp2));
while (iPos < m_size)
{
if ((iPos % 16) == 0)
{
if (sTmp1[0] != 0)
{
sTmp += "\n";
sTmp += sTmp1;
sTmp += sTmp2;
}
memset(sTmp1, 0, sizeof(sTmp1));
memset(sTmp2, 0, sizeof(sTmp2));
sprintf(sTmp2, "%s", pSpace2);
}
if (m_pCache[iPos] < 0x10)
{
sprintf(sTmp1, "%s0%X%s", sTmp1, m_pCache[iPos], pSpace1);
sprintf(sTmp2, "%s.", sTmp2);
}
else
{
sprintf(sTmp1, "%s%2X%s", sTmp1, m_pCache[iPos], pSpace1);
sprintf(sTmp2, "%s%c", sTmp2, m_pCache[iPos]);
}
iPos++;
}
int iTmp = strlen(sTmp1);
while (iTmp < 48)
{
sprintf(sTmp1, "%s ", sTmp1);
iTmp++;
}
sTmp += "\n";
sTmp += sTmp1;
sTmp += sTmp2;
return sTmp;
}
/**********************************************************************
* 功 能 : // 整理零碎内存,整理完后得到的是一片连续的内存区域
* 输入参数: //
* 输出参数: //
* 返 回 值: //
***********************************************************************/
void CacheManage::CollectFreeMemory()
{
UINT32 iPos = 0;
TNode<TCacheAllocStauts> *pNode = m_stautsList.Front();
while (pNode)
{
/* 数据移位,填充左边的空格(低位的空余内存) */
if (pNode->PTR_Value()->start > iPos)
{
memcpy(m_pCache+iPos, m_pCache + pNode->PTR_Value()->start, pNode->PTR_Value()->size);
*(pNode->PTR_Value()->pType) = m_pCache + iPos;
}
/* 将当前位置移动size大小,并检查下一个分配的内存 */
iPos += pNode->PTR_Value()->size;
pNode = m_stautsList.Next();
}
/* 将剩余的内存置0,并重置可分配内存的起始位置 */
memset(m_pCache + iPos, 0, m_size - iPos);
m_iPos = iPos;
}