自己的底層代碼庫(十五)——對象隊列

這也參照對象池的設計思想,隊列實際上就是一個對象池

但是隊列沒有對象池的malloc,free,只有PushObj,PopObj

m_Used列表只能先進先出,不能隨機訪問,不能遍歷

它具有和對象池一模一樣的分配子TObjectAllocator,隊列結點由Allocator動態分配


直接上代碼

TObjectQueue.h

#ifndef _TObjectQueue_h_
#define _TObjectQueue_h_

#include <windows.h>

#include "TBDLinkList.h"
#include "TTree.h"
#include "TObjectAllocator.h"

#include "CLock.h"

#include "tool.h"

//自增隊列
//
//該隊列自行申請對象所需內存空間
//其實也是一個Pool(FIFO,不可以隨機訪問的池)
template <class T>
class TObjectQueue
{
public:
	TObjectQueue();
	~TObjectQueue();

	//初始化函數
	//dwFirstObjCount:	隊列初始分配對象個數,不允許爲0
	//dwAddObjCount:	Obj不夠時,新增分配Obj個數,
	//					允許傳0,表示不夠時不開闢新內存,返回空
	//dwLock:			設置是否使用臨界區
	//					初始默認爲Enable,即使用臨界區
public:
	bool Init(DWORD dwFirstObjCount, 
		DWORD dwAddObjCount, 
		ContainerFlag dwLock = enum_EnableLock);

	//釋放隊列的所有分配子
public:
	void Release();

	//向隊列增加一個Obj
	//obj:	傳入參數,需要放入隊列的Obj
	//		隊列會自行分配空間拷貝Obj信息
	//		不需要調用者保存傳入的Obj
	//成功返回true
	//隊列已滿返回false
public:
	bool PushObj(T& obj);

	//從隊列取出一個Obj(移除)
	//obj:	傳出參數,放置取出的Obj信息
	//成功返回true
	//隊列已空返回false
public:
	bool PopObj(T& obj);

	//隊列長度不夠時,增加分配子,開闢新內存
private:
	bool AddObject(DWORD dwAddCount);

	//獲取當前各個列表使用情況
public:
	DWORD GetUsedListLen();
	DWORD GetFreeListLen();

private:
	TBDLinkList<T> m_Used;//使用中的Obj列表
	TBDLinkList<T> m_Free;//空閒Obj列表

	TBDLinkList<TObjectAllocator<T>> m_MemAllocList;//Obj對象池分配子管理鏈表
	DWORD m_dwAddObjCount;
};

#include "TObjectQueue.hpp"

#endif


TObjectQueue.hpp

#ifndef _TObjectQueue_hpp_
#define _TObjectQueue_hpp_

template <class T>
TObjectQueue<T>::TObjectQueue()
{
	m_Used.Init(enum_DisableLock);
	m_Free.Init(enum_DisableLock);

	m_MemAllocList.Init(enum_DisableLock);
	m_dwAddObjCount = 0;
}

template <class T>
TObjectQueue<T>::~TObjectQueue()
{
	Release();
}

template <class T>
bool TObjectQueue<T>::Init(DWORD dwFirstObjCount, DWORD dwAddObjCount, ContainerFlag dwLock)
{
	if (0 == dwFirstObjCount)
	{
		//初始化參數不正確
		return false;
	}
	else
	{
		m_dwAddObjCount = dwAddObjCount;

		m_Used.Init(dwLock);
		m_Free.Init(dwLock);

		m_MemAllocList.Init(dwLock);

		//申請分配子,開闢第一塊內存
		return AddObject(dwFirstObjCount);
	}
}

template <class T>
void TObjectQueue<T>::Release()
{
	m_Used.Init(enum_DisableLock);
	m_Free.Init(enum_DisableLock);

	TBDLinker<TObjectAllocator<T>> *pLinker = m_MemAllocList.PopHead();
	while (NULL != pLinker)
	{
		delete pLinker;
		pLinker = m_MemAllocList.PopHead();
	}
	m_MemAllocList.Init(enum_DisableLock);
	m_dwAddObjCount = 0;
}

template <class T>
bool TObjectQueue<T>::PushObj(T& obj)
{
	TBDLinker<T> *pLinker = m_Free.PopHead();
	if (NULL == pLinker)
	{
		if (AddObject(m_dwAddObjCount))
		{
			pLinker = m_Free.PopHead();
		}
	}

	if (NULL == pLinker)
	{
		return false;
	}
	else
	{
		memcpy(&(pLinker->m_Value), &obj, sizeof(T));
		return m_Used.PushTail(pLinker);
	}
}

template <class T>
bool TObjectQueue<T>::PopObj(T& obj)
{
	TBDLinker<T> *pLinker = m_Used.PopHead();
	
	if (NULL == pLinker)
	{
		return false;
	}
	else
	{
		memcpy(&obj, &(pLinker->m_Value), sizeof(T));
		return m_Free.PushTail(pLinker);
	}
}

template <class T>
bool TObjectQueue<T>::AddObject(DWORD dwAddCount)
{
	if (0 == dwAddCount)
	{
		return false;
	}
	else
	{
		TBDLinker<TObjectAllocator<T>> *pAllocLinker = new TBDLinker<TObjectAllocator<T>>;
		if (NULL == pAllocLinker)
		{
			return false;
		}
		pAllocLinker->Init();
		if (!pAllocLinker->m_Value.Init(dwAddCount, m_Free))
		{
			delete pAllocLinker;
			return false;
		}
		m_MemAllocList.PushTail(pAllocLinker);

		return true;
	}
}

template <class T>
DWORD TObjectQueue<T>::GetUsedListLen()
{
	return m_Used.GetLen();
}

template <class T>
DWORD TObjectQueue<T>::GetFreeListLen()
{
	return m_Free.GetLen();
}

#endif


發佈了54 篇原創文章 · 獲贊 14 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章