简单内存池

22 篇文章 0 订阅
#ifndef __BUFFER_MANAGER_H__
#define __BUFFER_MANAGER_H__

#include <list>
#include <iterator>

using std::list;
using std::iterator;

typedef unsigned char u_char;
typedef unsigned long u_long;
typedef unsigned short u_short;

/**************************************************************
类模板BufferManager<BufferNode>是一个用来管理内存的容器
模板功能:
         1.用作获取与回收缓冲块的容器(利用函数GetIdleBufferNode和RecycleIdleBufferNode)
         2.用来存取有用数据(利用函数RecycleIdleBufferNode和RemoveHeadBufferNode),相当于KK_List<BufferNode *, BufferNode *>
模板参数:
         BufferNode是一个结构体,它必须具有如下三个成员:
             u_char    * lpBuffer;           // 缓冲块地址(必须构造中就初始化为NULL)
             u_long      ulDataLength;       // 缓冲块内容长度(必须构造中就初始化为0)
             u_long      ulMemCapacity;      // 缓冲块大小(必须构造中就初始化为0)
当然,它也可以是一个继承自STORE_BUFFER(实现见当前文件)的结构体
**************************************************************/
template<typename BufferNode>
class BufferManager
{
private:
	typedef list<BufferNode *> lst_buffer_node;
	typedef typename list<BufferNode *>::iterator lst_iter;

public:
	~BufferManager();

	BufferNode * GetIdleBufferNode(u_long ulMinBufferSize);
	BufferNode * RemoveHeadBufferNode();
	void RecycleIdleBufferNode(BufferNode *& lpBufferNode);
	void TransferFrom(lst_buffer_node & lstBufferNodes);
	void TransferTo(lst_buffer_node & lstBufferNodes);
    void TransferFrom(BufferManager<BufferNode> & lstBufferNodes);
	void TransferTo(BufferManager<BufferNode> & lstBufferNodes);

private:
	lst_buffer_node     m_lstBufferNodes; // 可用的缓冲块节点链表
};

/**************************************************************
~BufferManager:
释放缓冲块给系统
**************************************************************/
template<typename BufferNode>
BufferManager<BufferNode>::~BufferManager()
{
    for (lst_iter iter = m_lstBufferNodes.begin(); iter != m_lstBufferNodes.end(); ++iter) {
		delete (*iter);
	}
	m_lstBufferNodes.clear();
}

/**************************************************************
GetIdleBufferNode:
获取一个至少有ulMinBufferSize个字节大小的缓冲块
**************************************************************/
template<typename BufferNode>
BufferNode * BufferManager<BufferNode>::GetIdleBufferNode(u_long ulMinBufferSize)
{
	BufferNode * lpUnuseBufferNode = NULL;
	if (m_lstBufferNodes.size() > 0) { // 如果管理器中有可用的缓冲块,先尝试拿下来,看是否可用
		lpUnuseBufferNode = m_lstBufferNodes.front();
		m_lstBufferNodes.pop_front();
	}

	if (NULL == lpUnuseBufferNode) { // 如果没有从管理器上得到缓冲块,则先申请一块(可视为申请了一个大小为0的缓冲块)
		lpUnuseBufferNode = new BufferNode;
	}

	// 如果当前获得的缓冲块大小不足ulMinBufferSize
	if (NULL != lpUnuseBufferNode && lpUnuseBufferNode->ulMemCapacity < ulMinBufferSize) {
		u_char * lpNewBuffer = new u_char[ulMinBufferSize];
		if (NULL != lpNewBuffer) { // 如果新的缓冲块申请成功,则用新的缓冲块替换原来的缓冲块,原来的缓冲块归还给系统
			delete [] lpUnuseBufferNode->lpBuffer;
			lpUnuseBufferNode->lpBuffer = lpNewBuffer;
			lpUnuseBufferNode->ulMemCapacity = ulMinBufferSize;
		}
		else if (lpUnuseBufferNode->ulMemCapacity > 0) { // 否则,如果获得的缓冲块可用(大小非0,亦即从当前管理器中获得的),归还给管理器
			RecycleIdleBufferNode(lpUnuseBufferNode);
		}
		else { // 如果获得的缓冲块的大小为0(不是从当前管理器中获得的),则归还给系统
			delete lpUnuseBufferNode;
			lpUnuseBufferNode = NULL;
		}
	}

	// 将缓冲块的内容长度置为0
	if (NULL != lpUnuseBufferNode) {
		lpUnuseBufferNode->ulDataLength = 0;
	}

	return lpUnuseBufferNode;
}

/**************************************************************
RemoveHeadBufferNode:
在功能2(存取数据)中做取数据的功能
**************************************************************/
template<typename BufferNode>
BufferNode * BufferManager<BufferNode>::RemoveHeadBufferNode()
{
	if (m_lstBufferNodes.size() > 0) {
	    BufferNode * lpBufferNode = m_lstBufferNodes.front();
        m_lstBufferNodes.pop_front();
        return lpBufferNode;
	}
	else {
		return NULL;
	}
}

/**************************************************************
RecycleIdleBufferNode:
在功能1(缓冲块管理)中做回收的功能
在功能2(存取数据)中做存数据的功能
**************************************************************/
template<typename BufferNode>
void BufferManager<BufferNode>::RecycleIdleBufferNode(BufferNode *& lpBufferNode)
{
	if (NULL != lpBufferNode) {
		m_lstBufferNodes.push_back(lpBufferNode);
		lpBufferNode = NULL;
	}
}

/**************************************************************
TransferFrom:
将一个lst_buffer_node的所有缓冲块(或是有用数据)移动到当前管理器
**************************************************************/
template<typename BufferNode>
void BufferManager<BufferNode>::TransferFrom(lst_buffer_node & lstBufferNodes)
{
	m_lstBufferNodes.splice(m_lstBufferNodes.end(), lstBufferNodes);
}

/**************************************************************
TransferTo:
将当前管理器的所有缓冲块(或是有用数据)移动到一个lst_buffer_node
**************************************************************/
template<typename BufferNode>
void BufferManager<BufferNode>::TransferTo(lst_buffer_node & lstBufferNodes)
{
	lstBufferNodes.splice(lstBufferNodes.end(), m_lstBufferNodes);
}

/**************************************************************
TransferFrom:
将一个BufferManager<BufferNode>的所有缓冲块(或是有用数据)移动到当前管理器
**************************************************************/
template<typename BufferNode>
void BufferManager<BufferNode>::TransferFrom(BufferManager<BufferNode> & lstBufferNodes)
{
    TransferFrom(lstBufferNodes.m_lstBufferNodes);
}

/**************************************************************
TransferTo:
将当前管理器的所有缓冲块(或是有用数据)移动到一个BufferManager<BufferNode>
**************************************************************/
template<typename BufferNode>
void BufferManager<BufferNode>::TransferTo(BufferManager<BufferNode> & lstBufferNodes)
{
    TransferTo(lstBufferNodes.m_lstBufferNodes);
}

/**************************************************************
STORE_BUFFER:
一般的缓冲块结构
**************************************************************/
struct STORE_BUFFER
{
	STORE_BUFFER() : lpBuffer(NULL), ulDataLength(0), ulMemCapacity(0)
	{

	}

	~STORE_BUFFER()
	{
		delete [] lpBuffer;
	}

	u_char    * lpBuffer;        // 缓冲块地址
	u_long      ulDataLength;    // 缓冲块内容长度
	u_long      ulMemCapacity;   // 缓冲块大小
};

#endif


 

#include <iostream>
using std::cout;
using std::endl;
#include <cstring>
#include "BufferManager.h"

int main(int argc, char * argv[], char * envi[])
{
    BufferManager<STORE_BUFFER> bufferFactory;
    BufferManager<STORE_BUFFER> dataManager;
    BufferManager<STORE_BUFFER> dataHandler;
    STORE_BUFFER * lpBufferNode = NULL;

    char hello[] = "Hello World";
    lpBufferNode = bufferFactory.GetIdleBufferNode(sizeof(hello));
    memcpy(lpBufferNode->lpBuffer, hello, sizeof(hello));
    lpBufferNode->ulDataLength = sizeof(hello);
    cout << "collect data to manager: " << lpBufferNode->lpBuffer << endl;
    dataManager.RecycleIdleBufferNode(lpBufferNode);

    char passion[] = "passion in my heart";
    lpBufferNode = bufferFactory.GetIdleBufferNode(sizeof(passion));
    memcpy(lpBufferNode->lpBuffer, passion, sizeof(passion));
    lpBufferNode->ulDataLength = sizeof(passion);
    cout << "collect data to manager: " << lpBufferNode->lpBuffer << endl;
    dataManager.RecycleIdleBufferNode(lpBufferNode);

    int count = 0;
    lpBufferNode = dataManager.RemoveHeadBufferNode();
    while (NULL != lpBufferNode) {
        ++count;
        cout << "manager data " << count << ": "<< lpBufferNode->lpBuffer << endl;
        bufferFactory.RecycleIdleBufferNode(lpBufferNode);
        cout << "   recycle to factory" << endl;
        lpBufferNode = dataManager.RemoveHeadBufferNode();
    }

    cout << "factory transfer to manager" << endl;
    bufferFactory.TransferTo(dataManager); // just test, do not do this in your codes

    char sweet[] = "passion is sweet, love makes weak";
    lpBufferNode = bufferFactory.GetIdleBufferNode(sizeof(sweet));
    memcpy(lpBufferNode->lpBuffer, sweet, sizeof(sweet));
    lpBufferNode->ulDataLength = sizeof(sweet);
    cout << "collect data to handler: " << lpBufferNode->lpBuffer << endl;
    dataHandler.RecycleIdleBufferNode(lpBufferNode);
    cout << "handler transfer from manager" << endl;
    dataHandler.TransferFrom(dataManager);

    count = 0;
    lpBufferNode = dataHandler.RemoveHeadBufferNode();
    while (NULL != lpBufferNode) {
        ++count;
        cout << "handler data " << count << ": "<< lpBufferNode->lpBuffer << endl;
        bufferFactory.RecycleIdleBufferNode(lpBufferNode);
        cout << "   recycle to factory" << endl;
        lpBufferNode = dataHandler.RemoveHeadBufferNode();
    }

	return 0;
}

由于VC对C++模板这块的支持程度不够, "typedef typename list<BufferNode *>::iterator lst_iter;"这句不能通过编译

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值