前不久,因为项目的要求对数据存取十分频繁,如果每次都是分配内存,然后释放,会产生大量的内存碎片,所以设计了一个数据池模板类,该类很简单,主要功能有:
1. 初始化数据池
2. 清空数据池
3. 取得一段数据缓冲区
4. 释放一段数据缓冲区
5. 取得缓冲区记录数
如何使用:
使用步骤如下:
1, 创建数据池:
CDataBuffer<MyStruct> Databuf;
Databuf.Init();
2, 如果你需要设置数据池的大小,可以调用SetMaxBufSize函数来完成,函数定义如下:
bool SetMaxBufSize(long lMaxBufSize); lMaxBufSize是要指定的数据池大小。
Databuf. SetMaxBufSize(10*1024*1024);//大小设为10M
3, 当你想取得一条记录时:
MyStruct * pData = Databuf.GetBuffer();
4, 在使用完该记录后:
Databuf. ReleaseBuffer(pData);
够简单的吧,好了,下面时程序的代码:
#if !defined(AFX_DATABUFFER_H__F5FDEB06_6C87_4D8B_AF80_06D47BA3B459__INCLUDED_)
#define AFX_DATABUFFER_H__F5FDEB06_6C87_4D8B_AF80_06D47BA3B459__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <list>
#include "MutexLock.h"
using namespace std;
//最大数据池容量 单位是BYTE
#define MAXBUFFERSIZE 10*1024*1024
template <class TData>
class CDataBuffer
{
public:
CDataBuffer()
{
//默认数据池容量为10M
m_lMaxBufferCount = MAXBUFFERSIZE/sizeof(TData);
}
virtual ~CDataBuffer(){Close();}
//取得一个数据缓冲区
TData * GetBuffer();
//释放数据缓冲区,这里没有真正释放,而是把数据存放到数据池中
bool ReleaseBuffer(TData * pData)
{
//先把数据缓冲清零
memset(pData, 0x00, sizeof(TData));
m_pMutex->Lock(1000);
if(m_lDataPool.size() >= m_lMaxBufferCount)
{//如果数据池已经满了, 只好把该缓冲区释放.
try
{
delete pData;
pData = NULL;
}
catch (...)
{
}
}
else
{
//数据池没有满,添加到数据池
m_lDataPool.push_back(pData);
}
m_pMutex->UnLock();
return true;
}
//取得数据池中有多少数据缓冲区
long GetBufferCount()
{
long lRet = 0;
m_pMutex->Lock(1000);
lRet = (long)m_lDataPool.size();
m_pMutex->UnLock();
return lRet;
}
//设置数据池允许的最大数据容量
bool SetMaxBufSize(long lMaxBufSize)
{
if(lMaxBufSize > 1024)
{
m_lMaxBufferCount = lMaxBufSize/sizeof(TData);
return true;
}
return false;
}
//取得数据池允许的最大数据容量
long GetMaxBufSize()
{
return m_lMaxBufferCount*sizeof(TData);
}
//初始化
bool Init();
//清空缓冲区
bool ClearBufferPool();
//
private:
//关闭
bool Close()
{
//清空数据池
ClearBufferPool();
//释放互斥区
if(m_pMutex != NULL)
{
delete m_pMutex;
m_pMutex = NULL;
}
return true;
}
private:
typedef list<TData* > BUFFER_LIST;
BUFFER_LIST m_lDataPool; //数据池
CMutexLock* m_pMutex; //互斥区
long m_lMaxBufferCount; //最大数据缓冲区数
};
//////////////////////////////////////////////////////////////////////////
template <class TData>
bool CDataBuffer<TData>::Init()
{
//创建缓冲区
m_pMutex = new CWinMutex;
if(m_pMutex == NULL)
{
return false;
}
return true;
}
template <class TData>
bool CDataBuffer<TData>::ClearBufferPool()
{
BUFFER_LIST::iterator first = m_lDataPool.begin();
BUFFER_LIST::iterator last = m_lDataPool.end();
TData * pData= NULL;
try
{
//轮询释放
while (first != last)
{
pData = (TData*)*first;
if(pData != NULL)
{
delete pData;
pData = NULL;
}
first++;
}
//清空列表
m_lDataPool.clear();
}
catch (...)
{
return false;
}
return true;
}
template <class TData>
TData* CDataBuffer<TData>::GetBuffer()
{
TData * pData = NULL;
m_pMutex->Lock(1000);
if(m_lDataPool.size() > 0)
{
//如果数据池中有空余的数据缓冲区,取出来
pData = (TData*)m_lDataPool.front();
//从数据池中删除
m_lDataPool.pop_front();
}
m_pMutex->UnLock();
if(pData == NULL)
{//没有找到空余数据,只好创建一个
pData = new TData;
}
//注意,如果内存耗尽,系统快崩溃时,这里取得的也是NULL指针
return pData;
}
//////////////////////////////////////////////////////////////////////////
#endif // !defined(AFX_DATABUFFER_H__F5FDEB06_6C87_4D8B_AF80_06D47BA3B459__INCLUDED_)
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <list>
#include "MutexLock.h"
using namespace std;
//最大数据池容量 单位是BYTE
#define MAXBUFFERSIZE 10*1024*1024
template <class TData>
class CDataBuffer
{
public:
CDataBuffer()
{
//默认数据池容量为10M
m_lMaxBufferCount = MAXBUFFERSIZE/sizeof(TData);
}
virtual ~CDataBuffer(){Close();}
//取得一个数据缓冲区
TData * GetBuffer();
//释放数据缓冲区,这里没有真正释放,而是把数据存放到数据池中
bool ReleaseBuffer(TData * pData)
{
//先把数据缓冲清零
memset(pData, 0x00, sizeof(TData));
m_pMutex->Lock(1000);
if(m_lDataPool.size() >= m_lMaxBufferCount)
{//如果数据池已经满了, 只好把该缓冲区释放.
try
{
delete pData;
pData = NULL;
}
catch (...)
{
}
}
else
{
//数据池没有满,添加到数据池
m_lDataPool.push_back(pData);
}
m_pMutex->UnLock();
return true;
}
//取得数据池中有多少数据缓冲区
long GetBufferCount()
{
long lRet = 0;
m_pMutex->Lock(1000);
lRet = (long)m_lDataPool.size();
m_pMutex->UnLock();
return lRet;
}
//设置数据池允许的最大数据容量
bool SetMaxBufSize(long lMaxBufSize)
{
if(lMaxBufSize > 1024)
{
m_lMaxBufferCount = lMaxBufSize/sizeof(TData);
return true;
}
return false;
}
//取得数据池允许的最大数据容量
long GetMaxBufSize()
{
return m_lMaxBufferCount*sizeof(TData);
}
//初始化
bool Init();
//清空缓冲区
bool ClearBufferPool();
//
private:
//关闭
bool Close()
{
//清空数据池
ClearBufferPool();
//释放互斥区
if(m_pMutex != NULL)
{
delete m_pMutex;
m_pMutex = NULL;
}
return true;
}
private:
typedef list<TData* > BUFFER_LIST;
BUFFER_LIST m_lDataPool; //数据池
CMutexLock* m_pMutex; //互斥区
long m_lMaxBufferCount; //最大数据缓冲区数
};
//////////////////////////////////////////////////////////////////////////
template <class TData>
bool CDataBuffer<TData>::Init()
{
//创建缓冲区
m_pMutex = new CWinMutex;
if(m_pMutex == NULL)
{
return false;
}
return true;
}
template <class TData>
bool CDataBuffer<TData>::ClearBufferPool()
{
BUFFER_LIST::iterator first = m_lDataPool.begin();
BUFFER_LIST::iterator last = m_lDataPool.end();
TData * pData= NULL;
try
{
//轮询释放
while (first != last)
{
pData = (TData*)*first;
if(pData != NULL)
{
delete pData;
pData = NULL;
}
first++;
}
//清空列表
m_lDataPool.clear();
}
catch (...)
{
return false;
}
return true;
}
template <class TData>
TData* CDataBuffer<TData>::GetBuffer()
{
TData * pData = NULL;
m_pMutex->Lock(1000);
if(m_lDataPool.size() > 0)
{
//如果数据池中有空余的数据缓冲区,取出来
pData = (TData*)m_lDataPool.front();
//从数据池中删除
m_lDataPool.pop_front();
}
m_pMutex->UnLock();
if(pData == NULL)
{//没有找到空余数据,只好创建一个
pData = new TData;
}
//注意,如果内存耗尽,系统快崩溃时,这里取得的也是NULL指针
return pData;
}
//////////////////////////////////////////////////////////////////////////
#endif // !defined(AFX_DATABUFFER_H__F5FDEB06_6C87_4D8B_AF80_06D47BA3B459__INCLUDED_)