BufferPool.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Author : Bruce Liang
  5. * Website : https://github.com/ldcsaa
  6. * Project : https://github.com/ldcsaa/HP-Socket
  7. * Blog : http://www.cnblogs.com/ldcsaa
  8. * Wiki : http://www.oschina.net/p/hp-socket
  9. * QQ Group : 44636872, 75375912
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. #pragma once
  24. #include "hpsocket/GlobalDef.h"
  25. #include "Singleton.h"
  26. #include "STLHelper.h"
  27. #include "RingBuffer.h"
  28. #include "PrivateHeap.h"
  29. #include "CriSec.h"
  30. template<class T> T* ConstructItemT(T*, CPrivateHeap& heap, int capacity, BYTE* pData, int length)
  31. {
  32. ASSERT(capacity > 0);
  33. int item_size = sizeof(T);
  34. T* pItem = (T*)heap.Alloc(item_size + capacity);
  35. BYTE* pHead = (BYTE*)pItem + item_size;
  36. return ::ConstructObject(pItem, heap, pHead, capacity, pData, length);
  37. }
  38. template<class T> void DestructItemT(T* pItem)
  39. {
  40. ASSERT(pItem != nullptr);
  41. CPrivateHeap& heap = pItem->GetPrivateHeap();
  42. ::DestructObject(pItem);
  43. heap.Free(pItem);
  44. }
  45. struct TItem
  46. {
  47. template<typename T> friend struct TSimpleList;
  48. template<typename T> friend class CNodePoolT;
  49. template<typename T> friend struct TItemListT;
  50. friend struct TBuffer;
  51. public:
  52. int Cat (const BYTE* pData, int length);
  53. int Cat (const TItem& other);
  54. int Fetch (BYTE* pData, int length);
  55. int Peek (BYTE* pData, int length);
  56. int Increase(int length);
  57. int Reduce (int length);
  58. void Reset (int first = 0, int last = 0);
  59. BYTE* Ptr () {return begin;}
  60. const BYTE* Ptr () const {return begin;}
  61. int Size () const {return (int)(end - begin);}
  62. int Remain () const {return capacity - (int)(end - head);}
  63. int Capacity() const {return capacity;}
  64. bool IsEmpty () const {return Size() == 0;}
  65. bool IsFull () const {return Remain() == 0;}
  66. CPrivateHeap& GetPrivateHeap() {return heap;}
  67. operator BYTE* () {return Ptr();}
  68. operator const BYTE* () const {return Ptr();}
  69. public:
  70. static TItem* Construct(CPrivateHeap& heap,
  71. int capacity = DEFAULT_ITEM_CAPACITY,
  72. BYTE* pData = nullptr,
  73. int length = 0)
  74. {
  75. return ::ConstructItemT((TItem*)(nullptr), heap, capacity, pData, length);
  76. }
  77. static void Destruct(TItem* pItem)
  78. {
  79. ::DestructItemT(pItem);
  80. }
  81. TItem(CPrivateHeap& hp, BYTE* pHead, int cap = DEFAULT_ITEM_CAPACITY, BYTE* pData = nullptr, int length = 0)
  82. : heap(hp), head(pHead), begin(pHead), end(pHead), capacity(cap), next(nullptr), last(nullptr)
  83. {
  84. if(pData != nullptr && length != 0)
  85. Cat(pData, length);
  86. }
  87. ~TItem() {}
  88. DECLARE_NO_COPY_CLASS(TItem)
  89. public:
  90. static const DWORD DEFAULT_ITEM_CAPACITY;
  91. private:
  92. CPrivateHeap& heap;
  93. private:
  94. TItem* next;
  95. TItem* last;
  96. int capacity;
  97. BYTE* head;
  98. BYTE* begin;
  99. BYTE* end;
  100. };
  101. template<class T> struct TSimpleList
  102. {
  103. public:
  104. T* PushFront(T* pItem)
  105. {
  106. if(pFront != nullptr)
  107. {
  108. pFront->last = pItem;
  109. pItem->next = pFront;
  110. }
  111. else
  112. {
  113. pItem->last = nullptr;
  114. pItem->next = nullptr;
  115. pBack = pItem;
  116. }
  117. pFront = pItem;
  118. ++size;
  119. return pItem;
  120. }
  121. T* PushBack(T* pItem)
  122. {
  123. if(pBack != nullptr)
  124. {
  125. pBack->next = pItem;
  126. pItem->last = pBack;
  127. }
  128. else
  129. {
  130. pItem->last = nullptr;
  131. pItem->next = nullptr;
  132. pFront = pItem;
  133. }
  134. pBack = pItem;
  135. ++size;
  136. return pItem;
  137. }
  138. T* PopFront()
  139. {
  140. T* pItem = pFront;
  141. if(pFront != pBack)
  142. {
  143. pFront = (T*)pFront->next;
  144. pFront->last = nullptr;
  145. }
  146. else if(pFront != nullptr)
  147. {
  148. pFront = nullptr;
  149. pBack = nullptr;
  150. }
  151. if(pItem != nullptr)
  152. {
  153. pItem->next = nullptr;
  154. pItem->last = nullptr;
  155. --size;
  156. }
  157. return pItem;
  158. }
  159. T* PopBack()
  160. {
  161. T* pItem = pBack;
  162. if(pFront != pBack)
  163. {
  164. pBack = (T*)pBack->last;
  165. pBack->next = nullptr;
  166. }
  167. else if(pBack != nullptr)
  168. {
  169. pFront = nullptr;
  170. pBack = nullptr;
  171. }
  172. if(pItem != nullptr)
  173. {
  174. pItem->next = nullptr;
  175. pItem->last = nullptr;
  176. --size;
  177. }
  178. return pItem;
  179. }
  180. TSimpleList<T>& Shift(TSimpleList<T>& other)
  181. {
  182. if(&other != this && other.size > 0)
  183. {
  184. if(size > 0)
  185. {
  186. pBack->next = other.pFront;
  187. other.pFront->last = pBack;
  188. }
  189. else
  190. {
  191. pFront = other.pFront;
  192. }
  193. pBack = other.pBack;
  194. size += other.size;
  195. other.Reset();
  196. }
  197. return *this;
  198. }
  199. void Clear()
  200. {
  201. if(size > 0)
  202. {
  203. T* pItem;
  204. while((pItem = PopFront()) != nullptr)
  205. T::Destruct(pItem);
  206. }
  207. }
  208. T* Front () const {return pFront;}
  209. T* Back () const {return pBack;}
  210. int Size () const {return size;}
  211. bool IsEmpty () const {return size == 0;}
  212. public:
  213. TSimpleList() {Reset();}
  214. ~TSimpleList() {Clear();}
  215. DECLARE_NO_COPY_CLASS(TSimpleList<T>)
  216. private:
  217. void Reset()
  218. {
  219. pFront = nullptr;
  220. pBack = nullptr;
  221. size = 0;
  222. }
  223. private:
  224. int size;
  225. T* pFront;
  226. T* pBack;
  227. };
  228. template<class T> class CNodePoolT
  229. {
  230. public:
  231. void PutFreeItem(T* pItem)
  232. {
  233. ASSERT(pItem != nullptr);
  234. if(!m_lsFreeItem.TryPut(pItem))
  235. T::Destruct(pItem);
  236. }
  237. void PutFreeItem(TSimpleList<T>& lsItem)
  238. {
  239. if(lsItem.IsEmpty())
  240. return;
  241. T* pItem;
  242. while((pItem = lsItem.PopFront()) != nullptr)
  243. PutFreeItem(pItem);
  244. }
  245. T* PickFreeItem()
  246. {
  247. T* pItem = nullptr;
  248. if(!m_lsFreeItem.TryGet(&pItem))
  249. pItem = T::Construct(m_heap, m_dwItemCapacity);
  250. ASSERT(pItem);
  251. pItem->Reset();
  252. return pItem;
  253. }
  254. void Prepare()
  255. {
  256. m_lsFreeItem.Reset(m_dwPoolSize);
  257. }
  258. void Clear()
  259. {
  260. m_lsFreeItem.Clear();
  261. m_heap.Reset();
  262. }
  263. public:
  264. void SetItemCapacity(DWORD dwItemCapacity) {m_dwItemCapacity = dwItemCapacity;}
  265. void SetPoolSize (DWORD dwPoolSize) {m_dwPoolSize = dwPoolSize;}
  266. void SetPoolHold (DWORD dwPoolHold) {m_dwPoolHold = dwPoolHold;}
  267. DWORD GetItemCapacity () {return m_dwItemCapacity;}
  268. DWORD GetPoolSize () {return m_dwPoolSize;}
  269. DWORD GetPoolHold () {return m_dwPoolHold;}
  270. CPrivateHeap& GetPrivateHeap() {return m_heap;}
  271. public:
  272. CNodePoolT( DWORD dwPoolSize = DEFAULT_POOL_SIZE,
  273. DWORD dwPoolHold = DEFAULT_POOL_HOLD,
  274. DWORD dwItemCapacity = DEFAULT_ITEM_CAPACITY)
  275. : m_dwPoolSize(dwPoolSize)
  276. , m_dwPoolHold(dwPoolHold)
  277. , m_dwItemCapacity(dwItemCapacity)
  278. {
  279. }
  280. ~CNodePoolT() {Clear();}
  281. DECLARE_NO_COPY_CLASS(CNodePoolT)
  282. public:
  283. static const DWORD DEFAULT_ITEM_CAPACITY;
  284. static const DWORD DEFAULT_POOL_SIZE;
  285. static const DWORD DEFAULT_POOL_HOLD;
  286. private:
  287. CPrivateHeap m_heap;
  288. DWORD m_dwItemCapacity;
  289. DWORD m_dwPoolSize;
  290. DWORD m_dwPoolHold;
  291. CRingPool<T> m_lsFreeItem;
  292. };
  293. template<class T> const DWORD CNodePoolT<T>::DEFAULT_ITEM_CAPACITY = TItem::DEFAULT_ITEM_CAPACITY;
  294. template<class T> const DWORD CNodePoolT<T>::DEFAULT_POOL_SIZE = DEFAULT_BUFFER_CACHE_POOL_SIZE;
  295. template<class T> const DWORD CNodePoolT<T>::DEFAULT_POOL_HOLD = DEFAULT_BUFFER_CACHE_POOL_HOLD;
  296. using CItemPool = CNodePoolT<TItem>;
  297. template<class T> struct TItemListT : public TSimpleList<T>
  298. {
  299. using __super = TSimpleList<T>;
  300. public:
  301. int PushTail(const BYTE* pData, int length)
  302. {
  303. ASSERT(length <= (int)itPool.GetItemCapacity());
  304. if(length > (int)itPool.GetItemCapacity())
  305. return 0;
  306. T* pItem = __super::PushBack(itPool.PickFreeItem());
  307. return pItem->Cat(pData, length);
  308. }
  309. int Cat(const BYTE* pData, int length)
  310. {
  311. int remain = length;
  312. while(remain > 0)
  313. {
  314. T* pItem = __super::Back();
  315. if(pItem == nullptr || pItem->IsFull())
  316. pItem = __super::PushBack(itPool.PickFreeItem());
  317. int cat = pItem->Cat(pData, remain);
  318. pData += cat;
  319. remain -= cat;
  320. }
  321. return length;
  322. }
  323. int Cat(const T* pItem)
  324. {
  325. return Cat(pItem->Ptr(), pItem->Size());
  326. }
  327. int Cat(const TItemListT<T>& other)
  328. {
  329. ASSERT(this != &other);
  330. int length = 0;
  331. for(T* pItem = other.Front(); pItem != nullptr; pItem = pItem->next)
  332. length += Cat(pItem);
  333. return length;
  334. }
  335. int Fetch(BYTE* pData, int length)
  336. {
  337. int remain = length;
  338. while(remain > 0 && __super::Size() > 0)
  339. {
  340. T* pItem = __super::Front();
  341. int fetch = pItem->Fetch(pData, remain);
  342. pData += fetch;
  343. remain -= fetch;
  344. if(pItem->IsEmpty())
  345. itPool.PutFreeItem(__super::PopFront());
  346. }
  347. return length - remain;
  348. }
  349. int Peek(BYTE* pData, int length)
  350. {
  351. int remain = length;
  352. T* pItem = __super::Front();
  353. while(remain > 0 && pItem != nullptr)
  354. {
  355. int peek = pItem->Peek(pData, remain);
  356. pData += peek;
  357. remain -= peek;
  358. pItem = pItem->next;
  359. }
  360. return length - remain;
  361. }
  362. int Increase(int length)
  363. {
  364. int remain = length;
  365. while(remain > 0)
  366. {
  367. T* pItem = __super::Back();
  368. if(pItem == nullptr || pItem->IsFull())
  369. {
  370. pItem = itPool.PickFreeItem();
  371. __super::PushBack(pItem);
  372. }
  373. remain -= pItem->Increase(remain);
  374. }
  375. return length - remain;
  376. }
  377. int Reduce(int length)
  378. {
  379. int remain = length;
  380. while(remain > 0 && __super::Size() > 0)
  381. {
  382. T* pItem = __super::Front();
  383. remain -= pItem->Reduce(remain);
  384. if(pItem->IsEmpty())
  385. itPool.PutFreeItem(__super::PopFront());
  386. }
  387. return length - remain;
  388. }
  389. void Release()
  390. {
  391. itPool.PutFreeItem(*this);
  392. }
  393. CNodePoolT<T>& GetItemPool() {return itPool;}
  394. public:
  395. TItemListT(CNodePoolT<T>& pool) : itPool(pool)
  396. {
  397. }
  398. private:
  399. CNodePoolT<T>& itPool;
  400. };
  401. using TItemList = TItemListT<TItem>;
  402. template<class T, class length_t = int, typename = enable_if_t<is_integral<typename decay<length_t>::type>::value>>
  403. struct TItemListExT : public TItemListT<T>
  404. {
  405. using __super = TItemListT<T>;
  406. public:
  407. T* PushFront(T* pItem)
  408. {
  409. length += pItem->Size();
  410. return __super::PushFront(pItem);
  411. }
  412. T* PushBack(T* pItem)
  413. {
  414. length += pItem->Size();
  415. return __super::PushBack(pItem);
  416. }
  417. T* PopFront()
  418. {
  419. T* pItem = __super::PopFront();
  420. if(pItem != nullptr)
  421. length -= pItem->Size();
  422. return pItem;
  423. }
  424. T* PopBack()
  425. {
  426. T* pItem = __super::PopBack();
  427. if(pItem != nullptr)
  428. length -= pItem->Size();
  429. return pItem;
  430. }
  431. TItemListExT& Shift(TItemListExT<T>& other)
  432. {
  433. if(&other != this && other.length > 0)
  434. {
  435. length += other.length;
  436. other.length = 0;
  437. __super::Shift(other);
  438. }
  439. return *this;
  440. }
  441. void Clear()
  442. {
  443. __super::Clear();
  444. length = 0;
  445. }
  446. void Release()
  447. {
  448. __super::Release();
  449. length = 0;
  450. }
  451. public:
  452. int PushTail(const BYTE* pData, int length)
  453. {
  454. int cat = __super::PushTail(pData, length);
  455. this->length += cat;
  456. return cat;
  457. }
  458. int Cat(const BYTE* pData, int length)
  459. {
  460. int cat = __super::Cat(pData, length);
  461. this->length += cat;
  462. return cat;
  463. }
  464. int Cat(const T* pItem)
  465. {
  466. int cat = __super::Cat(pItem->Ptr(), pItem->Size());
  467. this->length += cat;
  468. return cat;
  469. }
  470. int Cat(const TItemListT<T>& other)
  471. {
  472. int cat = __super::Cat(other);
  473. this->length += cat;
  474. return cat;
  475. }
  476. int Fetch(BYTE* pData, int length)
  477. {
  478. int fetch = __super::Fetch(pData, length);
  479. this->length -= fetch;
  480. return fetch;
  481. }
  482. int Increase(int length)
  483. {
  484. int increase = __super::Increase(length);
  485. this->length += increase;
  486. return increase;
  487. }
  488. int Reduce(int length)
  489. {
  490. int reduce = __super::Reduce(length);
  491. this->length -= reduce;
  492. return reduce;
  493. }
  494. typename decay<length_t>::type Length() const {return length;}
  495. int IncreaseLength (int length) {return (this->length += length);}
  496. int ReduceLength (int length) {return (this->length -= length);}
  497. public:
  498. TItemListExT(CNodePoolT<T>& pool) : TItemListT<T>(pool), length(0)
  499. {
  500. }
  501. ~TItemListExT()
  502. {
  503. ASSERT(length >= 0);
  504. }
  505. DECLARE_NO_COPY_CLASS(TItemListExT)
  506. private:
  507. length_t length;
  508. };
  509. using TItemListEx = TItemListExT<TItem>;
  510. using TItemListExV = TItemListExT<TItem, volatile int>;
  511. template<class T> struct TItemPtrT
  512. {
  513. public:
  514. T* Reset(T* pItem = nullptr)
  515. {
  516. if(m_pItem != nullptr)
  517. itPool.PutFreeItem(m_pItem);
  518. m_pItem = pItem;
  519. return m_pItem;
  520. }
  521. T* Attach(T* pItem)
  522. {
  523. return Reset(pItem);
  524. }
  525. T* Detach()
  526. {
  527. T* pItem = m_pItem;
  528. m_pItem = nullptr;
  529. return pItem;
  530. }
  531. T* New()
  532. {
  533. return Attach(itPool.PickFreeItem());
  534. }
  535. bool IsValid () {return m_pItem != nullptr;}
  536. T* operator -> () {return m_pItem;}
  537. T* operator = (T* pItem) {return Reset(pItem);}
  538. operator T* () {return m_pItem;}
  539. T*& PtrRef () {return m_pItem;}
  540. T* Ptr () {return m_pItem;}
  541. const T* Ptr () const {return m_pItem;}
  542. operator const T* () const {return m_pItem;}
  543. public:
  544. TItemPtrT(CNodePoolT<T>& pool, T* pItem = nullptr)
  545. : itPool(pool), m_pItem(pItem)
  546. {
  547. }
  548. TItemPtrT(TItemListT<T>& ls, T* pItem = nullptr)
  549. : itPool(ls.GetItemPool()), m_pItem(pItem)
  550. {
  551. }
  552. ~TItemPtrT()
  553. {
  554. Reset();
  555. }
  556. DECLARE_NO_COPY_CLASS(TItemPtrT)
  557. private:
  558. CNodePoolT<T>& itPool;
  559. T* m_pItem;
  560. };
  561. using TItemPtr = TItemPtrT<TItem>;
  562. class CBufferPool;
  563. struct TBuffer
  564. {
  565. template<typename T> friend struct TSimpleList;
  566. friend class CBufferPool;
  567. public:
  568. static TBuffer* Construct(CBufferPool& pool, ULONG_PTR dwID);
  569. static void Destruct(TBuffer* pBuffer);
  570. public:
  571. int Cat (const BYTE* pData, int len);
  572. int Cat (const TItem* pItem);
  573. int Cat (const TItemList& other);
  574. int Fetch (BYTE* pData, int length);
  575. int Peek (BYTE* pData, int length);
  576. int Reduce (int len);
  577. public:
  578. CCriSec& CriSec () {return cs;}
  579. TItemList& ItemList() {return items;}
  580. ULONG_PTR ID () const {return id;}
  581. int Length () const {return length;}
  582. bool IsValid () const {return id != 0;}
  583. DWORD GetFreeTime () const {return freeTime;}
  584. int GetCount () const {return 0;}
  585. private:
  586. int IncreaseLength (int len) {return (length += len);}
  587. int DecreaseLength (int len) {return (length -= len);}
  588. void Reset ();
  589. private:
  590. friend TBuffer* ConstructObject<>(TBuffer*, CPrivateHeap&, CItemPool&, ULONG_PTR&);
  591. friend void DestructObject<>(TBuffer*);
  592. TBuffer(CPrivateHeap& hp, CItemPool& itPool, ULONG_PTR dwID = 0)
  593. : heap(hp), items(itPool), id(dwID), length(0)
  594. {
  595. }
  596. ~TBuffer() {}
  597. DECLARE_NO_COPY_CLASS(TBuffer)
  598. private:
  599. CPrivateHeap& heap;
  600. private:
  601. ULONG_PTR id;
  602. int length;
  603. DWORD freeTime;
  604. private:
  605. TBuffer* next;
  606. TBuffer* last;
  607. CCriSec cs;
  608. TItemList items;
  609. };
  610. class CBufferPool
  611. {
  612. using TBufferList = CRingPool<TBuffer>;
  613. using TBufferQueue = CCASQueue<TBuffer>;
  614. using TBufferCache = CRingCache<TBuffer, ULONG_PTR, true>;
  615. public:
  616. void PutFreeBuffer (ULONG_PTR dwID);
  617. TBuffer* PutCacheBuffer (ULONG_PTR dwID);
  618. TBuffer* FindCacheBuffer (ULONG_PTR dwID);
  619. TBuffer* PickFreeBuffer (ULONG_PTR dwID);
  620. void PutFreeBuffer (TBuffer* pBuffer);
  621. void Prepare ();
  622. void Clear ();
  623. void ReleaseGCBuffer (BOOL bForce = FALSE);
  624. public:
  625. void SetItemCapacity (DWORD dwItemCapacity) {m_itPool.SetItemCapacity(dwItemCapacity);}
  626. void SetItemPoolSize (DWORD dwItemPoolSize) {m_itPool.SetPoolSize(dwItemPoolSize);}
  627. void SetItemPoolHold (DWORD dwItemPoolHold) {m_itPool.SetPoolHold(dwItemPoolHold);}
  628. void SetMaxCacheSize (DWORD dwMaxCacheSize) {m_dwMaxCacheSize = dwMaxCacheSize;}
  629. void SetBufferLockTime (DWORD dwBufferLockTime) {m_dwBufferLockTime = dwBufferLockTime;}
  630. void SetBufferPoolSize (DWORD dwBufferPoolSize) {m_dwBufferPoolSize = dwBufferPoolSize;}
  631. void SetBufferPoolHold (DWORD dwBufferPoolHold) {m_dwBufferPoolHold = dwBufferPoolHold;}
  632. DWORD GetItemCapacity () {return m_itPool.GetItemCapacity();}
  633. DWORD GetItemPoolSize () {return m_itPool.GetPoolSize();}
  634. DWORD GetItemPoolHold () {return m_itPool.GetPoolHold();}
  635. DWORD GetMaxCacheSize () {return m_dwMaxCacheSize;}
  636. DWORD GetBufferLockTime () {return m_dwBufferLockTime;}
  637. DWORD GetBufferPoolSize () {return m_dwBufferPoolSize;}
  638. DWORD GetBufferPoolHold () {return m_dwBufferPoolHold;}
  639. TBuffer* operator [] (ULONG_PTR dwID) {return FindCacheBuffer(dwID);}
  640. public:
  641. CBufferPool(DWORD dwPoolSize = DEFAULT_BUFFER_POOL_SIZE,
  642. DWORD dwPoolHold = DEFAULT_BUFFER_POOL_HOLD,
  643. DWORD dwLockTime = DEFAULT_BUFFER_LOCK_TIME,
  644. DWORD dwMaxCacheSize = DEFAULT_MAX_CACHE_SIZE)
  645. : m_dwBufferPoolSize(dwPoolSize)
  646. , m_dwBufferPoolHold(dwPoolHold)
  647. , m_dwBufferLockTime(dwLockTime)
  648. , m_dwMaxCacheSize(dwMaxCacheSize)
  649. {
  650. }
  651. ~CBufferPool() {Clear();}
  652. DECLARE_NO_COPY_CLASS(CBufferPool)
  653. public:
  654. CPrivateHeap& GetPrivateHeap() {return m_heap;}
  655. CItemPool& GetItemPool() {return m_itPool;}
  656. public:
  657. static const DWORD DEFAULT_MAX_CACHE_SIZE;
  658. static const DWORD DEFAULT_ITEM_CAPACITY;
  659. static const DWORD DEFAULT_ITEM_POOL_SIZE;
  660. static const DWORD DEFAULT_ITEM_POOL_HOLD;
  661. static const DWORD DEFAULT_BUFFER_LOCK_TIME;
  662. static const DWORD DEFAULT_BUFFER_POOL_SIZE;
  663. static const DWORD DEFAULT_BUFFER_POOL_HOLD;
  664. private:
  665. DWORD m_dwMaxCacheSize;
  666. DWORD m_dwBufferLockTime;
  667. DWORD m_dwBufferPoolSize;
  668. DWORD m_dwBufferPoolHold;
  669. CPrivateHeap m_heap;
  670. CItemPool m_itPool;
  671. TBufferCache m_bfCache;
  672. TBufferList m_lsFreeBuffer;
  673. TBufferQueue m_lsGCBuffer;
  674. };