www.pudn.com > myseelite_2007_06_28.zip > FreeList.h


/* 
*  Openmysee 
* 
*  This program is free software; you can redistribute it and/or modify 
*  it under the terms of the GNU General Public License as published by 
*  the Free Software Foundation; either version 2 of the License, or 
*  (at your option) any later version. 
* 
*  This program is distributed in the hope that it will be useful, 
*  but WITHOUT ANY WARRANTY; without even the implied warranty of 
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
*  GNU General Public License for more details. 
* 
*  You should have received a copy of the GNU General Public License 
*  along with this program; if not, write to the Free Software 
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
* 
*/ 
#pragma once 
 
#include  
#include  
 
using namespace std; 
 
// 对于大量频繁创建和销毁的对象,存在过多的内存分配/释放操作, 
// 使用一个空闲列表可以大大减少内存操作的频度,即: 
//     当需要创建对象时,从空闲列表头中提取一个,如果空闲列表为空,则创建对象 
//     当需要销毁对象时,将其放到空闲列表尾,如果空闲列表已满,则销毁对象 
// 实际上,本类还使用了Over-eager evaluation技术,即: 
//     每次需要创建对象时,都预计将会需要更多的对象,所以批量创建,返回第一个, 
// 并将剩下的放到空闲列表中,等待预计中的创建请求 
template 
class FreeList { 
public: 
	// 构造函数,传入列表大小,和批量分配的个数 
	FreeList(UINT maxFree, UINT batchNew) :  
		m_maxFree(maxFree), m_batchNew(batchNew), m_batchNewList(NULL) { 
		m_batchNewList = new T*[batchNew]; 
	}; 
	// 析构函数,清空列表,删除批量创建列表 
	~FreeList() { 
		/* 
		list::iterator it = m_freeList.begin(); 
		for(; it!= m_freeList.end(); ++it) { 
			delete (*it); 
			(*it) = NULL; 
		} 
		m_freeList.clear(); 
		*/ 
		while(!m_freeList.empty()) { 
			T* obj = m_freeList.top(); 
			m_freeList.pop(); 
			delete obj; 
		} 
		delete [] m_batchNewList; 
		m_batchNewList = NULL; 
	}; 
 
public: 
	// 分配并初始化 
	T* Allocate() { 
		// 如果空闲列表非空,则从列表头部提取一个 
		// 如果为空,则批量创建 
		T* obj = NULL; 
		if (!m_freeList.empty()) { 
			obj = m_freeList.top(); 
			_ASSERTE(_CrtIsValidHeapPointer(obj)); 
			m_freeList.pop(); 
		} 
		else { 
			// Over-eager evaluation, 每当需要new的时候,预计会需要更多 
			// 所以一次产生多个,以减少调用new的次数 
			for(UINT j = 0; j < m_batchNew; ++j) { 
				m_batchNewList[j] = new T(); 
				_ASSERTE(_CrtIsValidHeapPointer(m_batchNewList[j])); 
				if(!m_batchNewList[j]) { 
					printf("ATS::Allocate() out of memory!!! %d", GetLastError());  
					break; 
				} 
			} 
			if(j > 0) { 
				// 留着第一个返回,把后面的全部加到m_freeList中 
				obj = m_batchNewList[0]; 
				for(UINT i = 1; i < j; ++i) { 
					m_freeList.push(m_batchNewList[i]); 
				} 
			} 
		} 
 
		// 初始化,为以后的使用作准备 
		if(obj) 
			obj->Init(); 
 
		return obj; 
	}; 
	// 反初始化并释放 
	void Release(T* obj) { 
		if(!obj) 
			return; 
		_ASSERTE(_CrtIsValidHeapPointer(obj)); 
 
		// 首先调用反初始化,释放对象可能关联的资源 
		obj->Uninit(); 
 
		// 如果空闲列表未满,就放到空闲列表尾 
		// 如果已满,就销毁对象 
		if(m_freeList.size() < m_maxFree) 
			m_freeList.push(obj); 
		else { 
			delete obj; 
			obj = NULL; 
		} 
	}; 
private: 
	// 空闲的对象列表 
	stack m_freeList; 
	// 空闲对象的最大个数 
	const UINT m_maxFree; 
	// 批量创建的对象指针列表 
	T** m_batchNewList; 
	// 批量创建的对象个数 
	const UINT m_batchNew; 
};