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 return reinterpret_cast<pointer
>(CbAllocatorBase::allocate());
84 void deallocate(pointer p, size_type)
86 CbAllocatorBase::deallocate(p);
93 TypeInfo(
const std::type_info & ti) : mpTypeInfo(&ti)
98 bool operator<(
const TypeInfo & rhs)
const
100 return (*mpTypeInfo).before(*rhs.mpTypeInfo) ?
true :
false;
104 const std::type_info * mpTypeInfo;
108 typedef boost::shared_ptr<ReallocBuffer> ReallocBufferPtr;
110 class RCF_EXPORT ObjectPool
118 void enableCaching(std::size_t maxCount, boost::function1<void, T *> clearFunc)
120 enableCaching( (T *) NULL, maxCount, clearFunc);
124 void disableCaching()
126 disableCaching( (T *) NULL);
130 void enableCaching(T *, std::size_t maxCount, boost::function1<void, T *> clearFunc)
132 RCF::WriteLock lock(mObjPoolMutex);
133 RCF::TypeInfo ti(
typeid(T) );
134 mObjPool[ti].reset(
new RCF::ObjectPool::ObjList() );
135 mObjPool[ti]->mMaxSize = maxCount;
136 mObjPool[ti]->mOps.reset(
new RCF::ObjectPool::Ops<T>(clearFunc) );
140 void disableCaching(T *)
142 RCF::WriteLock lock(mObjPoolMutex);
143 RCF::TypeInfo ti(
typeid(T) );
144 mObjPool[ti]->mMaxSize = 0;
145 mObjPool[ti]->clear();
149 bool isCachingEnabled(T *)
151 ReadLock lock(mObjPoolMutex);
152 if (!mObjPool.empty())
154 RCF::TypeInfo ti(
typeid(T) );
155 ObjPool::iterator iter = mObjPool.find(ti);
156 if (iter != mObjPool.end())
158 if (iter->second->mMaxSize > 0)
167 MemOstreamPtr getMemOstreamPtr();
168 ReallocBufferPtr getReallocBufferPtr();
170 void enumerateWriteBuffers(std::vector<std::size_t> & bufferSizes);
171 void enumerateReadBuffers(std::vector<std::size_t> & bufferSizes);
173 void setBufferCountLimit(std::size_t bufferCountLimit);
174 std::size_t getBufferCountLimit();
176 void setBufferSizeLimit(std::size_t bufferSizeLimit);
177 std::size_t getBufferSizeLimit();
180 void getObj(boost::shared_ptr<T> & objPtr,
bool alwaysCreate =
true)
184 boost::shared_ptr<void> spv;
185 bool pfnDeleter =
false;
189 ReadLock lock(mObjPoolMutex);
191 if (mObjPool.empty())
204 TypeInfo ti(
typeid(T) );
205 ObjPool::iterator iter = mObjPool.find(ti);
206 if (iter == mObjPool.end())
219 ObjList & objList = *(iter->second);
220 Lock lock(objList.mMutex);
221 if (objList.mMaxSize == 0)
232 else if (objList.mVec.empty())
239 pv = objList.mVec.back();
240 pt =
static_cast<T *
>(pv);
241 objList.mVec.pop_back();
251 TypeInfo ti(
typeid(T) );
253 #if BOOST_VERSION < 103400
259 objPtr = boost::shared_ptr<T>(
261 boost::bind(&ObjectPool::putObj,
this, ti, _1));
268 objPtr = boost::shared_ptr<T>(
270 boost::bind(&ObjectPool::putObj,
this, ti, _1),
271 CbAllocator<void>(*this) );
277 objPtr = boost::shared_ptr<T>(pt);
281 void putObj(
const TypeInfo & ti,
void * pv)
283 ReadLock readLock(mObjPoolMutex);
284 RCF_ASSERT(!mObjPool.empty());
285 ObjPool::iterator iter = mObjPool.find(ti);
286 RCF_ASSERT(iter != mObjPool.end());
287 ObjList & objList = *(iter->second);
288 Lock lock(objList.mMutex);
289 if (objList.mVec.size() >= objList.mMaxSize)
293 objList.mOps->kill(pv);
297 objList.mOps->clear(pv);
298 objList.mVec.push_back(pv);
306 virtual void kill(
void * pv) = 0;
307 virtual void clear(
void * pv) = 0;
311 class Ops :
public I_Ops
314 Ops(boost::function1<void, T *> clearFunc) :
315 mClearFunc(clearFunc)
321 T * pt =
static_cast<T *
>(pv);
325 void clear(
void * pv)
329 T * pt =
static_cast<T *
>(pv);
334 boost::function1<void, T *> mClearFunc;
337 class ObjList : boost::noncopyable
340 ObjList() : mMaxSize(0)
344 std::size_t mMaxSize;
345 std::vector<void *> mVec;
346 boost::scoped_ptr<I_Ops> mOps;
350 for (std::size_t i=0; i<mVec.size(); ++i)
358 typedef boost::shared_ptr<ObjList> ObjListPtr;
360 typedef std::map< TypeInfo, ObjListPtr > ObjPool;
361 ReadWriteMutex mObjPoolMutex;
366 friend class CbAllocatorBase;
369 void putPcb(
void * pcb);
371 void putMemOstream(MemOstream * pOs);
372 void putReallocBuffer(ReallocBuffer * pRb);
374 std::size_t mBufferCountLimit;
375 std::size_t mBufferSizeLimit;
378 std::vector< MemOstream * > mOsPool;
381 std::vector< ReallocBuffer * > mRbPool;
384 std::vector< void * > mCbPool;
386 template<
typename T,
typename Spt,
typename PtrList,
typename Pfn>
391 Mutex & ptrListMutex,
397 Lock lock(ptrListMutex);
410 #if BOOST_VERSION < 103400
416 spt = boost::shared_ptr<T>(
418 boost::bind(pfn,
this, _1));
425 spt = boost::shared_ptr<T>(
427 boost::bind(pfn,
this, _1),
428 CbAllocator<void>(*this) );
436 RCF_EXPORT ObjectPool & getObjectPool();
440 #endif // ! INCLUDE_RCF_OBJECTPOOL_HPP