19 #ifndef INCLUDE_RCF_OBJECTPOOL_HPP
20 #define INCLUDE_RCF_OBJECTPOOL_HPP
24 #include <boost/bind.hpp>
25 #include <boost/shared_ptr.hpp>
27 #include <RCF/Tools.hpp>
28 #include <RCF/ThreadLibrary.hpp>
32 static const std::size_t CbSize = 128;
36 class RCF_EXPORT CbAllocatorBase
40 CbAllocatorBase(ObjectPool & objectPool);
41 CbAllocatorBase(
const CbAllocatorBase & rhs);
44 void deallocate(
void * pcb) ;
47 ObjectPool & mObjectPool;
51 class CbAllocator :
public CbAllocatorBase
56 typedef value_type* pointer;
57 typedef std::size_t size_type;
58 typedef std::ptrdiff_t difference_type;
63 typedef CbAllocator<U> other;
66 CbAllocator(ObjectPool & objectPool) : CbAllocatorBase(objectPool)
71 CbAllocator(
const CbAllocator<U> & rhs) : CbAllocatorBase(rhs)
77 typename std::allocator<void>::const_pointer = 0)
79 BOOST_STATIC_ASSERT(
sizeof(T) <= CbSize );
80 RCF_ASSERT_EQ(cnt , 1);
81 RCF_UNUSED_VARIABLE(cnt);
82 return reinterpret_cast<pointer
>(CbAllocatorBase::allocate());
85 void deallocate(pointer p, size_type)
87 CbAllocatorBase::deallocate(p);
94 TypeInfo(
const std::type_info & ti) : mpTypeInfo(&ti)
99 bool operator<(
const TypeInfo & rhs)
const
101 return (*mpTypeInfo).before(*rhs.mpTypeInfo) ?
true :
false;
105 const std::type_info * mpTypeInfo;
109 typedef boost::shared_ptr<ReallocBuffer> ReallocBufferPtr;
111 class RCF_EXPORT ObjectPool
119 void enableCaching(std::size_t maxCount, boost::function1<void, T *> clearFunc)
121 enableCaching( (T *) NULL, maxCount, clearFunc);
125 void disableCaching()
127 disableCaching( (T *) NULL);
131 void enableCaching(T *, std::size_t maxCount, boost::function1<void, T *> clearFunc)
133 RCF::WriteLock lock(mObjPoolMutex);
134 RCF::TypeInfo ti(
typeid(T) );
135 mObjPool[ti].reset(
new RCF::ObjectPool::ObjList() );
136 mObjPool[ti]->mMaxSize = maxCount;
137 mObjPool[ti]->mOps.reset(
new RCF::ObjectPool::Ops<T>(clearFunc) );
141 void disableCaching(T *)
143 RCF::WriteLock lock(mObjPoolMutex);
144 RCF::TypeInfo ti(
typeid(T) );
145 mObjPool[ti]->mMaxSize = 0;
146 mObjPool[ti]->clear();
150 bool isCachingEnabled(T *)
152 ReadLock lock(mObjPoolMutex);
153 if (!mObjPool.empty())
155 RCF::TypeInfo ti(
typeid(T) );
156 ObjPool::iterator iter = mObjPool.find(ti);
157 if (iter != mObjPool.end())
159 if (iter->second->mMaxSize > 0)
168 MemOstreamPtr getMemOstreamPtr();
169 ReallocBufferPtr getReallocBufferPtr();
171 void enumerateWriteBuffers(std::vector<std::size_t> & bufferSizes);
172 void enumerateReadBuffers(std::vector<std::size_t> & bufferSizes);
174 void setBufferCountLimit(std::size_t bufferCountLimit);
175 std::size_t getBufferCountLimit();
177 void setBufferSizeLimit(std::size_t bufferSizeLimit);
178 std::size_t getBufferSizeLimit();
181 void getObj(boost::shared_ptr<T> & objPtr,
bool alwaysCreate =
true)
185 boost::shared_ptr<void> spv;
186 bool pfnDeleter =
false;
190 ReadLock poolLock(mObjPoolMutex);
192 if (mObjPool.empty())
205 TypeInfo ti(
typeid(T) );
206 ObjPool::iterator iter = mObjPool.find(ti);
207 if (iter == mObjPool.end())
220 ObjList & objList = *(iter->second);
221 Lock listLock(objList.mMutex);
222 if (objList.mMaxSize == 0)
233 else if (objList.mVec.empty())
240 pv = objList.mVec.back();
241 pt =
static_cast<T *
>(pv);
242 objList.mVec.pop_back();
252 TypeInfo ti(
typeid(T) );
254 #if BOOST_VERSION < 103400
260 objPtr = boost::shared_ptr<T>(
262 boost::bind(&ObjectPool::putObj,
this, ti, _1));
269 objPtr = boost::shared_ptr<T>(
271 boost::bind(&ObjectPool::putObj,
this, ti, _1),
272 CbAllocator<void>(*this) );
278 objPtr = boost::shared_ptr<T>(pt);
282 void putObj(
const TypeInfo & ti,
void * pv)
284 ReadLock readLock(mObjPoolMutex);
285 RCF_ASSERT(!mObjPool.empty());
286 ObjPool::iterator iter = mObjPool.find(ti);
287 RCF_ASSERT(iter != mObjPool.end());
288 ObjList & objList = *(iter->second);
289 Lock lock(objList.mMutex);
290 if (objList.mVec.size() >= objList.mMaxSize)
294 objList.mOps->kill(pv);
298 objList.mOps->clear(pv);
299 objList.mVec.push_back(pv);
307 virtual void kill(
void * pv) = 0;
308 virtual void clear(
void * pv) = 0;
312 class Ops :
public I_Ops
315 Ops(boost::function1<void, T *> clearFunc) :
316 mClearFunc(clearFunc)
322 T * pt =
static_cast<T *
>(pv);
326 void clear(
void * pv)
330 T * pt =
static_cast<T *
>(pv);
335 boost::function1<void, T *> mClearFunc;
338 class ObjList : boost::noncopyable
341 ObjList() : mMaxSize(0)
345 std::size_t mMaxSize;
346 std::vector<void *> mVec;
347 boost::scoped_ptr<I_Ops> mOps;
351 for (std::size_t i=0; i<mVec.size(); ++i)
359 typedef boost::shared_ptr<ObjList> ObjListPtr;
361 typedef std::map< TypeInfo, ObjListPtr > ObjPool;
362 ReadWriteMutex mObjPoolMutex;
367 friend class CbAllocatorBase;
370 void putPcb(
void * pcb);
372 void putMemOstream(MemOstream * pOs);
373 void putReallocBuffer(ReallocBuffer * pRb);
375 std::size_t mBufferCountLimit;
376 std::size_t mBufferSizeLimit;
379 std::vector< MemOstream * > mOsPool;
382 std::vector< ReallocBuffer * > mRbPool;
385 std::vector< void * > mCbPool;
387 template<
typename T,
typename Spt,
typename PtrList,
typename Pfn>
392 Mutex & ptrListMutex,
398 Lock lock(ptrListMutex);
411 #if BOOST_VERSION < 103400
417 spt = boost::shared_ptr<T>(
419 boost::bind(pfn,
this, _1));
426 spt = boost::shared_ptr<T>(
428 boost::bind(pfn,
this, _1),
429 CbAllocator<void>(*this) );
437 RCF_EXPORT ObjectPool & getObjectPool();
441 #endif // ! INCLUDE_RCF_OBJECTPOOL_HPP