一个简单的数据池模板类

前不久,因为项目的要求对数据存取十分频繁,如果每次都是分配内存,然后释放,会产生大量的内存碎片,所以设计了一个数据池模板类,该类很简单,主要功能有:

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_)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章