⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objectpool.h.svn-base

📁 moses开源的机器翻译系统
💻 SVN-BASE
字号:
// $Id$/* ---------------------------------------------------------------- *//* Copyright 2005 (c) by RWTH Aachen - Lehrstuhl fuer Informatik VI *//* Richard Zens                                                     *//* ---------------------------------------------------------------- */#ifndef OBJECTPOOL_H_#define OBJECTPOOL_H_#include <vector>#include <deque>#include <string>#include <iostream>#include <iterator>#include "Util.h"/*** * template class for pool of objects * - useful if many small objects are frequently created and destroyed * - allocates memory for N objects at a time * - separates memory allocation from constructor/destructor calls * - prevents memory leaks */template<typename T> class ObjectPool { public:  typedef T Object; private:  std::string name;  size_t idx,dIdx,N;  std::vector<Object*> data;  std::vector<size_t> dataSize;  std::deque<Object*> freeObj;  int mode; public:  static const int cleanUpOnDestruction=1;  static const int hasTrivialDestructor=2;  // constructor arguments:  //   N: initial number of objects to allocate memory at a time  //   m & cleanUpOnDestruction = clean up objects in destructor  //   m & hasTrivialDestructor = the object type has a trivial destructor,  //            i.e. no sub-object uses dynamically allocated memory  //            note: not equivalent to empty destructor  //         -> more efficient (destructor calls can be omitted),   //            note: looks like memory leak, but is not  ObjectPool(std::string name_="T",size_t N_=100000,int m=cleanUpOnDestruction)    : name(name_),idx(0),dIdx(0),N(N_),mode(m) {allocate();}		// main accesss functions:		// get pointer to object via default or copy constructor		Object* get() {return new (getPtr()) Object;}		Object* get(const Object& x) {return new (getPtr()) Object(x);}  		// get pointer to uninitialized memory, 		// WARNING: use only if you know what you are doing !		// useful for non-default constructors, you have to use placement new		Object* getPtr() {			if(freeObj.size()) {				Object* rv=freeObj.back();freeObj.pop_back();rv->~Object();return rv;}			if(idx==dataSize[dIdx]) {idx=0; if(++dIdx==data.size()) allocate();}			return data[dIdx]+idx++;		}		// return object(s) to pool for reuse		// note: objects are not destroyed here, but in 'getPtr'/'destroyObjects',		//       otherwise 'destroyObjects' would have to check the freeObj-stack 		//       before each destructor call		void freeObject(Object* x) {freeObj.push_back(x);}		template<class fwiter> void freeObjects(fwiter b,fwiter e) {			for(;b!=e;++b) this->free(*b);}		// destroy all objects, but do not free memory		void reset() {destroyObjects();idx=0;dIdx=0;freeObj.clear();}		// destroy all objects and free memory		void cleanUp() {			reset(); for(size_t i=0;i<data.size();++i) free(data[i]);			data.clear();dataSize.clear();		}		~ObjectPool() {if(mode & cleanUpOnDestruction) cleanUp();}		void printInfo(std::ostream& out) const {			out<<"OPOOL ("<<name<<") info: "<<data.size()<<" "<<dataSize.size()<<" "				 <<freeObj.size()<<"\n"<<idx<<" "<<dIdx<<" "<<N<<"\n";			std::copy(dataSize.begin(),dataSize.end(),								std::ostream_iterator<size_t>(out," "));			out<<"\n\n";		} private:		void destroyObjects() {			if(mode & hasTrivialDestructor) return;			for(size_t i=0;i<=dIdx;++i) {				size_t lastJ= (i<dIdx ? dataSize[i] : idx);				for(size_t j=0;j<lastJ;++j) (data[i]+j)->~Object();}		}		// allocate memory for a N objects, for follow-up allocations,		// the block size is doubled every time		// if allocation fails, block size is reduced by 1/4		void allocate() {			try {				if(dataSize.empty()) dataSize.push_back(N); 				else dataSize.push_back(dataSize.back()*2);				void *m=malloc(sizeof(Object)*dataSize.back());				while(!m) {					dataSize.back()=static_cast<size_t>(dataSize.back()*0.75);					m=malloc(sizeof(Object)*dataSize.back());				}				data.push_back(static_cast<Object*>(m)); 			}			catch (const std::exception& e) {				TRACE_ERR("caught std::exception: "<<e.what()								 <<" in ObjectPool::allocate(), name: "<<name<<", last size: "								 <<dataSize.back()<<"\n");				TRACE_ERR("OPOOL info: "<<data.size()<<" "<<dataSize.size()<<" "								 <<freeObj.size()<<"\n"<<idx<<" "<<dIdx<<" "<<N<<"\n");				std::copy(dataSize.begin(),dataSize.end(),									std::ostream_iterator<size_t>(std::cerr," "));				TRACE_ERR("\n");				throw;			}		}};#endif //OBJECTPOOL_H_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -