一個簡單的數據池模板類

前不久,因爲項目的要求對數據存取十分頻繁,如果每次都是分配內存,然後釋放,會產生大量的內存碎片,所以設計了一個數據池模板類,該類很簡單,主要功能有:

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

 

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