ArrayPool.hpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:18k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #ifndef ARRAY_POOL_HPP
  14. #define ARRAY_POOL_HPP
  15. #include <ndb_global.h>
  16. #include <pc.hpp>
  17. #include <ErrorReporter.hpp>
  18. #include <NdbMem.h>
  19. #include <Bitmask.hpp>
  20. template <class T> class Array;
  21. template <class T> class SLList;
  22. template <class T> class DLList;
  23. template <class T> class DLHashTable;
  24. /**
  25.  * Template class used for implementing an
  26.  *   pool of object (in an array with a free list)
  27.  */
  28. template <class T>
  29. class ArrayPool {
  30. public:
  31.   ArrayPool();
  32.   ~ArrayPool();
  33.   
  34.   /**
  35.    * Set the size of the pool
  36.    *
  37.    * Note, can currently only be called once
  38.    */
  39.   bool setSize(Uint32 noOfElements);
  40.   inline Uint32 getNoOfFree() const {
  41.     return noOfFree;
  42.   }
  43.   inline Uint32 getSize() const {
  44.     return size;
  45.   }
  46.   /**
  47.    * Update p value for ptr according to i value 
  48.    */
  49.   void getPtr(Ptr<T> &);
  50.   void getPtr(ConstPtr<T> &) const;
  51.   void getPtr(Ptr<T> &, bool CrashOnBoundaryError);
  52.   void getPtr(ConstPtr<T> &, bool CrashOnBoundaryError) const;
  53.   
  54.   /**
  55.    * Get pointer for i value
  56.    */
  57.   T * getPtr(Uint32 i);
  58.   const T * getConstPtr(Uint32 i) const;
  59.   T * getPtr(Uint32 i, bool CrashOnBoundaryError);
  60.   const T * getConstPtr(Uint32 i, bool CrashOnBoundaryError) const;
  61.   /**
  62.    * Update p & i value for ptr according to <b>i</b> value 
  63.    */
  64.   void getPtr(Ptr<T> &, Uint32 i);
  65.   void getPtr(ConstPtr<T> &, Uint32 i) const;
  66.   void getPtr(Ptr<T> &, Uint32 i, bool CrashOnBoundaryError);
  67.   void getPtr(ConstPtr<T> &, Uint32 i, bool CrashOnBoundaryError) const;
  68.   /**
  69.    * Allocate an object from pool - update Ptr
  70.    *
  71.    * Return i
  72.    */
  73.   bool seize(Ptr<T> &);
  74.   /**
  75.    * Allocate object <b>i</b> from pool - update Ptr
  76.    */
  77.   bool seizeId(Ptr<T> &, Uint32 i);
  78.   /**
  79.    * Check if <b>i</b> is allocated.
  80.    */
  81.   bool findId(Uint32 i) const;
  82.   /**
  83.    * Return an object to pool
  84.    */
  85.   void release(Uint32 i);
  86.   /**
  87.    * Return an object to pool
  88.    */
  89.   void release(Ptr<T> &);
  90. #ifdef ARRAY_GUARD
  91.   /**
  92.    *  Checks if i is a correct seized record
  93.    *
  94.    *  @note Since this is either an expensive method, 
  95.    *        or needs bitmask stuff, this method is only 
  96.    *        recommended for debugging.
  97.    *
  98.    */
  99.   bool isSeized(Uint32 i) const {
  100.     if (i>=size) return false;
  101.     return BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i);
  102.   }
  103. #endif
  104. protected:
  105.   friend class Array<T>;
  106.   friend class SLList<T>;
  107.   friend class DLList<T>;
  108.   friend class DLHashTable<T>;
  109.   /**
  110.    * Allocate <b>n</b> consecutive object from pool
  111.    *   return base
  112.    */
  113.   Uint32 seizeN(Uint32 n);
  114.   /**
  115.    * Deallocate <b>n<b> consecutive object to pool
  116.    *  starting from base
  117.    */
  118.   void releaseN(Uint32 base, Uint32 n);
  119. public:
  120.   /**
  121.    * Release a singel linked list in o(1)
  122.    * @param first i-value of first element in list
  123.    * @param last  i-value of last element in list
  124.    * @note nextPool must be used as next pointer in list
  125.    */
  126.   void releaseList(Uint32 n, Uint32 first, Uint32 last);
  127.   //private:
  128. #ifdef DEBUG
  129.   Uint32 getNoOfFree2() const {
  130.     Uint32 c2 = size;
  131.     for(Uint32 i = 0; i<((size + 31)>> 5); i++){
  132.       Uint32 w = theAllocatedBitmask[i];
  133.       for(Uint32 j = 0; j<32; j++){
  134. if((w & 1) == 1){
  135.   c2--;
  136. }
  137. w >>= 1;
  138.       }
  139.     }
  140.     return c2;
  141.   }
  142.   Uint32 getNoOfFree3() const {
  143.     Uint32 c = 0;
  144.     Ptr<T> p;
  145.     p.i = firstFree;
  146.     while(p.i != RNIL){
  147.       c++;
  148.       p.p = &theArray[p.i];
  149.       p.i = p.p->next;
  150.     }
  151.     return c;
  152.   }
  153. #endif
  154. protected:
  155.   Uint32 firstFree;
  156.   Uint32 size;
  157.   Uint32 noOfFree;
  158.   T * theArray;
  159.   Uint32 bitmaskSz;
  160.   Uint32 *theAllocatedBitmask;
  161. };
  162. template <class T>
  163. inline
  164. ArrayPool<T>::ArrayPool(){
  165.   firstFree = RNIL;
  166.   size = 0;
  167.   noOfFree = 0;
  168.   theArray = 0;
  169. #ifdef ARRAY_GUARD
  170.   theAllocatedBitmask = 0;
  171. #endif
  172. }
  173. template <class T>
  174. inline
  175. ArrayPool<T>::~ArrayPool(){
  176.   if(theArray != 0){
  177.     NdbMem_Free(theArray);
  178.     theArray = 0;
  179. #ifdef ARRAY_GUARD
  180.     delete []theAllocatedBitmask;
  181.     theAllocatedBitmask = 0;
  182. #endif
  183.   }
  184. }
  185.   
  186. /**
  187.  * Set the size of the pool
  188.  *
  189.  * Note, can currently only be called once
  190.  */
  191. template <class T>
  192. inline
  193. bool
  194. ArrayPool<T>::setSize(Uint32 noOfElements){
  195.   if(size == 0){
  196.     if(noOfElements == 0)
  197.       return true;
  198.     theArray = (T *)NdbMem_Allocate(noOfElements * sizeof(T));
  199.     if(theArray == 0)
  200.       return false;
  201.     size = noOfElements;
  202.     noOfFree = noOfElements;
  203.     /**
  204.      * Set next pointers
  205.      */
  206.     T * t = &theArray[0];
  207.     for(Uint32 i = 0; i<size; i++){
  208.       t->nextPool = (i + 1);
  209.       t++;
  210.     }
  211.     theArray[size-1].nextPool = RNIL;
  212.     firstFree = 0;
  213. #ifdef ARRAY_GUARD
  214.     bitmaskSz = (noOfElements + 31) >> 5;
  215.     theAllocatedBitmask = new Uint32[bitmaskSz];
  216.     BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask);
  217. #endif
  218.     
  219.     return true;
  220.   }
  221.   return false;
  222. }
  223.   
  224. template <class T>
  225. inline
  226. void
  227. ArrayPool<T>::getPtr(Ptr<T> & ptr){
  228.   Uint32 i = ptr.i;
  229.   if(i < size){
  230.     ptr.p = &theArray[i];
  231. #ifdef ARRAY_GUARD
  232.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  233.       return;
  234.     /**
  235.      * Getting a non-seized element
  236.      */
  237.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  238. #endif
  239.   } else {
  240.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  241.   }
  242. }
  243. template <class T>
  244. inline
  245. void
  246. ArrayPool<T>::getPtr(ConstPtr<T> & ptr) const {
  247.   Uint32 i = ptr.i;
  248.   if(i < size){
  249.     ptr.p = &theArray[i];
  250. #ifdef ARRAY_GUARD
  251.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  252.       return;
  253.     /**
  254.      * Getting a non-seized element
  255.      */
  256.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  257. #endif
  258.   } else {
  259.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  260.   }
  261. }
  262. template <class T>
  263. inline
  264. void
  265. ArrayPool<T>::getPtr(Ptr<T> & ptr, Uint32 i){
  266.   ptr.i = i;
  267.   if(i < size){
  268.     ptr.p = &theArray[i];
  269. #ifdef ARRAY_GUARD
  270.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  271.       return;
  272.     /**
  273.      * Getting a non-seized element
  274.      */
  275.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  276. #endif
  277.   } else {
  278.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  279.   }
  280. }
  281. template <class T>
  282. inline
  283. void
  284. ArrayPool<T>::getPtr(ConstPtr<T> & ptr, Uint32 i) const {
  285.   ptr.i = i;
  286.   if(i < size){
  287.     ptr.p = &theArray[i];
  288. #ifdef ARRAY_GUARD
  289.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  290.       return;
  291.     /**
  292.      * Getting a non-seized element
  293.      */
  294.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  295. #endif
  296.   } else {
  297.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  298.   }
  299. }
  300.   
  301. template <class T>
  302. inline
  303. T * 
  304. ArrayPool<T>::getPtr(Uint32 i){
  305.   if(i < size){
  306. #ifdef ARRAY_GUARD
  307.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  308.       return &theArray[i];
  309.     /**
  310.      * Getting a non-seized element
  311.      */
  312.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  313.     return 0;
  314. #else
  315.     return &theArray[i];
  316. #endif
  317.   } else {
  318.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  319.     return 0;
  320.   }
  321. }
  322. template <class T>
  323. inline
  324. const T * 
  325. ArrayPool<T>::getConstPtr(Uint32 i) const {
  326.   if(i < size){
  327. #ifdef ARRAY_GUARD
  328.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  329.       return &theArray[i];
  330.     /**
  331.      * Getting a non-seized element
  332.      */
  333.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  334.     return 0;
  335. #else
  336.     return &theArray[i];
  337. #endif
  338.   } else {
  339.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  340.     return 0;
  341.   }
  342. }
  343. template <class T>
  344. inline
  345. void
  346. ArrayPool<T>::getPtr(Ptr<T> & ptr, bool CrashOnBoundaryError){
  347.   Uint32 i = ptr.i;
  348.   if(i < size){
  349.     ptr.p = &theArray[i];
  350. #ifdef ARRAY_GUARD
  351.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  352.       return;
  353.     /**
  354.      * Getting a non-seized element
  355.      */
  356.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  357. #endif
  358.   } else {
  359.     ptr.i = RNIL;
  360.   }
  361. }
  362. template <class T>
  363. inline
  364. void
  365. ArrayPool<T>::getPtr(ConstPtr<T> & ptr, bool CrashOnBoundaryError) const {
  366.   Uint32 i = ptr.i;
  367.   if(i < size){
  368.     ptr.p = &theArray[i];
  369. #ifdef ARRAY_GUARD
  370.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  371.       return;
  372.     /**
  373.      * Getting a non-seized element
  374.      */
  375.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  376. #endif
  377.   } else {
  378.     ptr.i = RNIL;
  379.   }
  380. }
  381. template <class T>
  382. inline
  383. void
  384. ArrayPool<T>::getPtr(Ptr<T> & ptr, Uint32 i, bool CrashOnBoundaryError){
  385.   ptr.i = i;
  386.   if(i < size){
  387.     ptr.p = &theArray[i];
  388. #ifdef ARRAY_GUARD
  389.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  390.       return;
  391.     /**
  392.      * Getting a non-seized element
  393.      */
  394.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  395. #endif
  396.   } else {
  397.     ptr.i = RNIL;
  398.   }
  399. }
  400. template <class T>
  401. inline
  402. void
  403. ArrayPool<T>::getPtr(ConstPtr<T> & ptr, Uint32 i, 
  404.      bool CrashOnBoundaryError) const {
  405.   ptr.i = i;
  406.   if(i < size){
  407.     ptr.p = &theArray[i];
  408. #ifdef ARRAY_GUARD
  409.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  410.       return;
  411.     /**
  412.      * Getting a non-seized element
  413.      */
  414.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  415. #endif
  416.   } else {
  417.     ptr.i = RNIL;
  418.   }
  419. }
  420.   
  421. template <class T>
  422. inline
  423. T * 
  424. ArrayPool<T>::getPtr(Uint32 i, bool CrashOnBoundaryError){
  425.   if(i < size){
  426. #ifdef ARRAY_GUARD
  427.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  428.       return &theArray[i];
  429.     /**
  430.      * Getting a non-seized element
  431.      */
  432.     ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
  433.     return 0;
  434. #else
  435.     return &theArray[i];
  436. #endif
  437.   } else {
  438.     return 0;
  439.   }
  440. }
  441. template <class T>
  442. inline
  443. const T * 
  444. ArrayPool<T>::getConstPtr(Uint32 i, bool CrashOnBoundaryError) const {
  445.   if(i < size){
  446. #ifdef ARRAY_GUARD
  447.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
  448.       return &theArray[i];
  449.     /**
  450.      * Getting a non-seized element
  451.      */
  452.     ErrorReporter::handleAssert("ArrayPool<T>::getConstPtr", __FILE__,__LINE__);
  453.     return 0;
  454. #else
  455.     return &theArray[i];
  456. #endif
  457.   } else {
  458.     return 0;
  459.   }
  460. }
  461.   
  462. /**
  463.  * Allocate an object from pool - update Ptr
  464.  *
  465.  * Return i
  466.  */
  467. template <class T>
  468. inline
  469. bool
  470. ArrayPool<T>::seize(Ptr<T> & ptr){
  471.   Uint32 ff = firstFree;
  472.   if(ff != RNIL){
  473.     firstFree = theArray[ff].nextPool;
  474.     
  475.     ptr.i = ff;
  476.     ptr.p = &theArray[ff];
  477. #ifdef ARRAY_GUARD
  478.     if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, ff)){
  479.       BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, ff);
  480.       noOfFree--;
  481.       return true;
  482.     } else {
  483.       /**
  484.        * Seizing an already seized element
  485.        */
  486.       ErrorReporter::handleAssert("ArrayPool<T>::seize", __FILE__, __LINE__);
  487.       return false;
  488.     }
  489. #else
  490.     noOfFree--;
  491.     return true;
  492. #endif
  493.   }
  494.   ptr.i = RNIL;
  495.   ptr.p = NULL;
  496.   return false;
  497. }
  498. template <class T>
  499. inline
  500. bool
  501. ArrayPool<T>::seizeId(Ptr<T> & ptr, Uint32 i){
  502.   Uint32 ff = firstFree;
  503.   Uint32 prev = RNIL;
  504.   while(ff != i && ff != RNIL){
  505.     prev = ff;
  506.     ff = theArray[ff].nextPool;
  507.   }
  508.   
  509.   if(ff != RNIL){
  510.     if(prev == RNIL)
  511.       firstFree = theArray[ff].nextPool;
  512.     else
  513.       theArray[prev].nextPool = theArray[ff].nextPool;
  514.     
  515.     ptr.i = ff;
  516.     ptr.p = &theArray[ff];
  517. #ifdef ARRAY_GUARD
  518.     if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, ff)){
  519.       BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, ff);
  520.       noOfFree--;
  521.       return true;
  522.     } else {
  523.       /**
  524.        * Seizing an already seized element
  525.        */
  526.       ErrorReporter::handleAssert("ArrayPool<T>::seizeId", __FILE__, __LINE__);
  527.       return false;
  528.     }
  529. #else
  530.     noOfFree--;
  531.     return true;
  532. #endif
  533.   }
  534.   ptr.i = RNIL;
  535.   ptr.p = NULL;
  536.   return false;
  537. }
  538. template <class T>
  539. inline
  540. bool
  541. ArrayPool<T>::findId(Uint32 i) const {
  542.   if (i >= size)
  543.     return false;
  544.   Uint32 ff = firstFree;
  545.   while(ff != i && ff != RNIL){
  546.     ff = theArray[ff].nextPool;
  547.   }
  548.   return (ff == RNIL);
  549. }
  550. template<class T>
  551. Uint32
  552. ArrayPool<T>::seizeN(Uint32 n){
  553.   Uint32 curr = firstFree;
  554.   Uint32 prev = RNIL;
  555.   Uint32 sz = 0;
  556.   while(sz < n && curr != RNIL){
  557.     if(theArray[curr].nextPool == (curr + 1)){
  558.       sz++;
  559.     } else {
  560.       sz = 0;
  561.       prev = curr;
  562.     }
  563.     curr = theArray[curr].nextPool;
  564.   }
  565.   if(sz != n){
  566.     return RNIL;
  567.   }
  568.   const Uint32 base = curr - n;
  569.   if(base == firstFree){
  570.     firstFree = curr;
  571.   } else {
  572.     theArray[prev].nextPool = curr;
  573.   }
  574.   
  575.   noOfFree -= n;
  576. #ifdef ARRAY_GUARD
  577.   for(Uint32 j = base; j<curr; j++){
  578.     if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, j)){
  579.       BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, j);
  580.     } else {
  581.       /**
  582.        * Seizing an already seized element
  583.        */
  584.       ErrorReporter::handleAssert("ArrayPool<T>::seize", __FILE__, __LINE__);
  585.       return RNIL;
  586.     }
  587.   }
  588. #endif
  589.   return base;
  590. }
  591. template<class T>
  592. inline
  593. void 
  594. ArrayPool<T>::releaseN(Uint32 base, Uint32 n){
  595.   Uint32 curr = firstFree;
  596.   Uint32 prev = RNIL;
  597.   while(curr < base){
  598.     prev = curr;
  599.     curr = theArray[curr].nextPool;
  600.   }
  601.   if(curr == firstFree){
  602.     firstFree = base;
  603.   } else {
  604.     theArray[prev].nextPool = base;
  605.   }
  606.   const Uint32 end = base + n;
  607.   for(Uint32 i = base; i<end; i++){
  608. #ifdef ARRAY_GUARD
  609.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
  610.       BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
  611.     } else {
  612.       /**
  613.        * Relesing a already released element
  614.        */
  615.     ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
  616.       return;
  617.     }
  618. #endif
  619.     theArray[i].nextPool = i + 1;
  620.   }
  621.   theArray[end-1].nextPool = curr;
  622.   noOfFree += n;
  623. }
  624. template<class T>
  625. inline
  626. void 
  627. ArrayPool<T>::releaseList(Uint32 n, Uint32 first, Uint32 last){
  628.   if(first < size && last < size){
  629.     Uint32 ff = firstFree;
  630.     firstFree = first;
  631.     theArray[last].nextPool = ff;
  632.     noOfFree += n;
  633. #ifdef ARRAY_GUARD
  634.     Uint32 tmp = first;
  635.     for(Uint32 i = 0; i<n; i++){
  636.       if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, tmp)){
  637. BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, tmp);
  638.       } else {
  639. /**
  640.  * Relesing a already released element
  641.  */
  642. ErrorReporter::handleAssert("ArrayPool<T>::releaseList", 
  643.     __FILE__, __LINE__);
  644. return;
  645.       }
  646.       tmp = theArray[tmp].nextPool;
  647.     }
  648. #endif
  649.     return;
  650.   }
  651.   ErrorReporter::handleAssert("ArrayPool<T>::releaseList", __FILE__, __LINE__);
  652. }
  653. /**
  654.  * Return an object to pool
  655.  */
  656. template <class T>
  657. inline
  658. void
  659. ArrayPool<T>::release(Uint32 _i){
  660.   const Uint32 i = _i;
  661.   if(i < size){
  662.     Uint32 ff = firstFree;
  663.     theArray[i].nextPool = ff;
  664.     firstFree = i;
  665. #ifdef ARRAY_GUARD
  666.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
  667.       BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
  668.       noOfFree++;
  669.       return;
  670.     }
  671.     /**
  672.      * Relesing a already released element
  673.      */
  674.     ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
  675. #endif
  676.     noOfFree++;
  677.     return;
  678.   }
  679.   ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
  680. }
  681. /**
  682.  * Return an object to pool
  683.  */
  684. template <class T>
  685. inline
  686. void
  687. ArrayPool<T>::release(Ptr<T> & ptr){
  688.   Uint32 i = ptr.i;
  689.   if(i < size){
  690.     Uint32 ff = firstFree;
  691.     theArray[i].nextPool = ff;
  692.     firstFree = i;
  693. #ifdef ARRAY_GUARD
  694.     if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
  695.       BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
  696.       //assert(noOfFree() == noOfFree2());
  697.       noOfFree++;
  698.       return;
  699.     }
  700.     /**
  701.      * Relesing a already released element
  702.      */
  703.     ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
  704. #endif
  705.     noOfFree++;
  706.     return;
  707.   }
  708.   ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
  709. }
  710. template <class T>
  711. class UnsafeArrayPool : public ArrayPool<T> {
  712. public:
  713.   /**
  714.    * Update p value for ptr according to i value 
  715.    *   ignore if it's allocated or not
  716.    */
  717.   void getPtrForce(Ptr<T> &);
  718.   void getPtrForce(ConstPtr<T> &) const;
  719.   T * getPtrForce(Uint32 i);
  720.   const T * getConstPtrForce(Uint32 i) const;
  721.   void getPtrForce(Ptr<T> &, Uint32 i);
  722.   void getPtrForce(ConstPtr<T> &, Uint32 i) const;
  723. };
  724. template <class T>
  725. inline
  726. void 
  727. UnsafeArrayPool<T>::getPtrForce(Ptr<T> & ptr){
  728.   Uint32 i = ptr.i;
  729.   if(i < this->size){
  730.     ptr.p = &this->theArray[i];
  731.   } else {
  732.     ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr", 
  733. __FILE__, __LINE__);
  734.   }
  735. }
  736. template <class T>
  737. inline
  738. void 
  739. UnsafeArrayPool<T>::getPtrForce(ConstPtr<T> & ptr) const{
  740.   Uint32 i = ptr.i;
  741.   if(i < this->size){
  742.     ptr.p = &this->theArray[i];
  743.   } else {
  744.     ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr", 
  745. __FILE__, __LINE__);
  746.   }
  747. }
  748. template <class T>
  749. inline
  750. T * 
  751. UnsafeArrayPool<T>::getPtrForce(Uint32 i){
  752.   if(i < this->size){
  753.     return &this->theArray[i];
  754.   } else {
  755.     ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr", 
  756. __FILE__, __LINE__);
  757.     return 0;
  758.   }
  759. }
  760. template <class T>
  761. inline
  762. const T * 
  763. UnsafeArrayPool<T>::getConstPtrForce(Uint32 i) const {
  764.   if(i < this->size){
  765.     return &this->theArray[i];
  766.   } else {
  767.     ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
  768. __FILE__, __LINE__);
  769.     return 0;
  770.   }
  771. }
  772. template <class T>
  773. inline
  774. void 
  775. UnsafeArrayPool<T>::getPtrForce(Ptr<T> & ptr, Uint32 i){
  776.   ptr.i = i;
  777.   if(i < this->size){
  778.     ptr.p = &this->theArray[i];
  779.     return ;
  780.   } else {
  781.     ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr", 
  782. __FILE__, __LINE__);
  783.   }
  784. }
  785. template <class T>
  786. inline
  787. void 
  788. UnsafeArrayPool<T>::getPtrForce(ConstPtr<T> & ptr, Uint32 i) const{
  789.   ptr.i = i;
  790.   if(i < this->size){
  791.     ptr.p = &this->theArray[i];
  792.     return ;
  793.   } else {
  794.     ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr", 
  795. __FILE__, __LINE__);
  796.   }
  797. }
  798. #endif