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

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 DL_HASHTABLE2_HPP
  14. #define DL_HASHTABLE2_HPP
  15. #include <ndb_global.h>
  16. #include "ArrayList.hpp"
  17. /**
  18.  * DLHashTable2 is a DLHashTable variant meant for cases where different
  19.  * DLHashTable instances share a common pool (based on a union U).
  20.  *
  21.  * Calls T constructor after seize from pool and T destructor before
  22.  * release (in all forms) into pool.
  23.  */
  24. template <class T, class U>
  25. class DLHashTable2 {
  26. public:
  27.   DLHashTable2(ArrayPool<U> & thePool);
  28.   ~DLHashTable2();
  29.   
  30.   /**
  31.    * Set the no of bucket in the hashtable
  32.    *
  33.    * Note, can currently only be called once
  34.    */
  35.   bool setSize(Uint32 noOfElements);
  36.   /**
  37.    * Seize element from pool - return i
  38.    *
  39.    * Note must be either added using <b>add</b> or released 
  40.    * using <b>release</b>
  41.    */
  42.   bool seize(Ptr<T> &);
  43.   /**
  44.    * Add an object to the hashtable
  45.    */
  46.   void add(Ptr<T> &);
  47.   
  48.   /**
  49.    * Find element key in hashtable update Ptr (i & p) 
  50.    *   (using key.equal(...))
  51.    * @return true if found and false otherwise
  52.    */
  53.   bool find(Ptr<T> &, const T & key) const;
  54.   /**
  55.    * Update i & p value according to <b>i</b>
  56.    */
  57.   void getPtr(Ptr<T> &, Uint32 i) const;
  58.   /**
  59.    * Get element using ptr.i (update ptr.p)
  60.    */
  61.   void getPtr(Ptr<T> &) const;
  62.   /**
  63.    * Get P value for i
  64.    */
  65.   T * getPtr(Uint32 i) const;
  66.   /**
  67.    * Remove element (and set Ptr to removed element)
  68.    * Note does not return to pool
  69.    */
  70.   void remove(Ptr<T> &, const T & key);
  71.   /**
  72.    * Remove element
  73.    * Note does not return to pool
  74.    */
  75.   void remove(Uint32 i);
  76.   /**
  77.    * Remove element
  78.    * Note does not return to pool
  79.    */
  80.   void remove(Ptr<T> &);
  81.   /**
  82.    * Remove all elements, but dont return them to pool
  83.    */
  84.   void removeAll();
  85.   
  86.   /**
  87.    * Remove element (and set Ptr to removed element)
  88.    * And return element to pool
  89.    */
  90.   void release(Ptr<T> &, const T & key);
  91.   /**
  92.    * Remove element and return to pool
  93.    */
  94.   void release(Uint32 i);
  95.   /**
  96.    * Remove element and return to pool
  97.    */
  98.   void release(Ptr<T> &);
  99.   
  100.   class Iterator {
  101.   public:
  102.     Ptr<T> curr;
  103.     Uint32 bucket;
  104.     inline bool isNull() const { return curr.isNull();}
  105.     inline void setNull() { curr.setNull(); }
  106.   };
  107.   /**
  108.    * Sets curr.p according to curr.i
  109.    */
  110.   void getPtr(Iterator & iter) const ;
  111.   /**
  112.    * First element in bucket
  113.    */
  114.   bool first(Iterator & iter) const;
  115.   
  116.   /**
  117.    * Next Element
  118.    *
  119.    * param iter - A "fully set" iterator
  120.    */
  121.   bool next(Iterator & iter) const;
  122.   /**
  123.    * Get next element starting from bucket
  124.    *
  125.    * @param bucket - Which bucket to start from
  126.    * @param iter - An "uninitialized" iterator
  127.    */
  128.   bool next(Uint32 bucket, Iterator & iter) const;
  129.   
  130. private:
  131.   Uint32 mask;
  132.   Uint32 * hashValues;
  133.   ArrayPool<U> & thePool;
  134. };
  135. template<class T, class U>
  136. inline
  137. DLHashTable2<T, U>::DLHashTable2(ArrayPool<U> & _pool)
  138.   : thePool(_pool)
  139. {
  140.   mask = 0;
  141.   hashValues = 0;
  142. }
  143. template<class T, class U>
  144. inline
  145. DLHashTable2<T, U>::~DLHashTable2(){
  146.   if(hashValues != 0)
  147.     delete [] hashValues;
  148. }
  149. template<class T, class U>
  150. inline
  151. bool
  152. DLHashTable2<T, U>::setSize(Uint32 size){
  153.   Uint32 i = 1;
  154.   while(i < size) i *= 2;
  155.   if(mask == (i - 1)){
  156.     /**
  157.      * The size is already set to <b>size</b>
  158.      */
  159.     return true;
  160.   }
  161.   if(mask != 0){
  162.     /**
  163.      * The mask is already set
  164.      */
  165.     return false;
  166.   }
  167.   
  168.   mask = (i - 1);
  169.   hashValues = new Uint32[i];
  170.   for(Uint32 j = 0; j<i; j++)
  171.     hashValues[j] = RNIL;
  172.   
  173.   return true;
  174. }
  175. template<class T, class U>
  176. inline
  177. void
  178. DLHashTable2<T, U>::add(Ptr<T> & obj){
  179.   const Uint32 hv = obj.p->hashValue() & mask;
  180.   const Uint32 i  = hashValues[hv];
  181.   
  182.   if(i == RNIL){
  183.     hashValues[hv] = obj.i;
  184.     obj.p->nextHash = RNIL;
  185.     obj.p->prevHash = RNIL;
  186.   } else {
  187.     
  188.     T * tmp = (T*)thePool.getPtr(i);    // cast
  189.     tmp->prevHash = obj.i;
  190.     obj.p->nextHash = i;
  191.     obj.p->prevHash = RNIL;
  192.     
  193.     hashValues[hv] = obj.i;
  194.   }
  195. }
  196. /**
  197.  * First element
  198.  */
  199. template<class T, class U>
  200. inline
  201. bool
  202. DLHashTable2<T, U>::first(Iterator & iter) const {
  203.   Uint32 i = 0;
  204.   while(i <= mask && hashValues[i] == RNIL) i++;
  205.   if(i <= mask){
  206.     iter.bucket = i;
  207.     iter.curr.i = hashValues[i];
  208.     iter.curr.p = (T*)thePool.getPtr(iter.curr.i);      // cast
  209.     return true;
  210.   } else {
  211.     iter.curr.i = RNIL;
  212.   }
  213.   return false;
  214. }
  215. template<class T, class U>
  216. inline
  217. bool
  218. DLHashTable2<T, U>::next(Iterator & iter) const {
  219.   if(iter.curr.p->nextHash == RNIL){
  220.     Uint32 i = iter.bucket + 1;
  221.     while(i <= mask && hashValues[i] == RNIL) i++;
  222.     if(i <= mask){
  223.       iter.bucket = i;
  224.       iter.curr.i = hashValues[i];
  225.       iter.curr.p = (T*)thePool.getPtr(iter.curr.i);    // cast
  226.       return true;
  227.     } else {
  228.       iter.curr.i = RNIL;
  229.       return false;
  230.     }
  231.   }
  232.   
  233.   iter.curr.i = iter.curr.p->nextHash;
  234.   iter.curr.p = (T*)thePool.getPtr(iter.curr.i);        // cast
  235.   return true;
  236. }
  237. template<class T, class U>
  238. inline
  239. void
  240. DLHashTable2<T, U>::remove(Ptr<T> & ptr, const T & key){
  241.   const Uint32 hv = key.hashValue() & mask;  
  242.   
  243.   Uint32 i;
  244.   T * p;
  245.   Ptr<T> prev;
  246.   prev.i = RNIL;
  247.   i = hashValues[hv];
  248.   while(i != RNIL){
  249.     p = (T*)thePool.getPtr(i);  // cast
  250.     if(key.equal(* p)){
  251.       const Uint32 next = p->nextHash;
  252.       if(prev.i == RNIL){
  253. hashValues[hv] = next;
  254.       } else {
  255. prev.p->nextHash = next;
  256.       }
  257.       
  258.       if(next != RNIL){
  259. T * nextP = (T*)thePool.getPtr(next);   // cast
  260. nextP->prevHash = prev.i;
  261.       }
  262.       ptr.i = i;
  263.       ptr.p = p;
  264.       return;
  265.     }
  266.     prev.p = p;
  267.     prev.i = i;
  268.     i = p->nextHash;
  269.   }
  270.   ptr.i = RNIL;
  271. }
  272. template<class T, class U>
  273. inline
  274. void
  275. DLHashTable2<T, U>::release(Ptr<T> & ptr, const T & key){
  276.   const Uint32 hv = key.hashValue() & mask;  
  277.   
  278.   Uint32 i;
  279.   T * p;
  280.   Ptr<T> prev;
  281.   prev.i = RNIL;
  282.   i = hashValues[hv];
  283.   while(i != RNIL){
  284.     p = (T*)thePool.getPtr(i);  // cast
  285.     if(key.equal(* p)){
  286.       const Uint32 next = p->nextHash;
  287.       if(prev.i == RNIL){
  288. hashValues[hv] = next;
  289.       } else {
  290. prev.p->nextHash = next;
  291.       }
  292.       
  293.       if(next != RNIL){
  294. T * nextP = (T*)thePool.getPtr(next);   // cast
  295. nextP->prevHash = prev.i;
  296.       }
  297.       p->~T();  // dtor
  298.       thePool.release(i);
  299.       ptr.i = i;
  300.       ptr.p = p;        // invalid
  301.       return;
  302.     }
  303.     prev.p = p;
  304.     prev.i = i;
  305.     i = p->nextHash;
  306.   }
  307.   ptr.i = RNIL;
  308. }
  309. template<class T, class U>
  310. inline
  311. void
  312. DLHashTable2<T, U>::remove(Uint32 i){
  313.   Ptr<T> tmp;
  314.   tmp.i = i;
  315.   tmp.p = (T*)thePool.getPtr(i);        // cast
  316.   remove(tmp);
  317. }
  318. template<class T, class U>
  319. inline
  320. void
  321. DLHashTable2<T, U>::release(Uint32 i){
  322.   Ptr<T> tmp;
  323.   tmp.i = i;
  324.   tmp.p = (T*)thePool.getPtr(i);        // cast
  325.   release(tmp);
  326. }
  327. template<class T, class U>
  328. inline
  329. void 
  330. DLHashTable2<T, U>::remove(Ptr<T> & ptr){
  331.   const Uint32 next = ptr.p->nextHash;
  332.   const Uint32 prev = ptr.p->prevHash;
  333.   if(prev != RNIL){
  334.     T * prevP = (T*)thePool.getPtr(prev);       // cast
  335.     prevP->nextHash = next;
  336.   } else {
  337.     const Uint32 hv = ptr.p->hashValue() & mask;  
  338.     hashValues[hv] = next;
  339.   }
  340.   
  341.   if(next != RNIL){
  342.     T * nextP = (T*)thePool.getPtr(next);       // cast
  343.     nextP->prevHash = prev;
  344.   }
  345. }
  346. template<class T, class U>
  347. inline
  348. void 
  349. DLHashTable2<T, U>::release(Ptr<T> & ptr){
  350.   const Uint32 next = ptr.p->nextHash;
  351.   const Uint32 prev = ptr.p->prevHash;
  352.   if(prev != RNIL){
  353.     T * prevP = (T*)thePool.getPtr(prev);       // cast
  354.     prevP->nextHash = next;
  355.   } else {
  356.     const Uint32 hv = ptr.p->hashValue() & mask;  
  357.     hashValues[hv] = next;
  358.   }
  359.   
  360.   if(next != RNIL){
  361.     T * nextP = (T*)thePool.getPtr(next);       // cast
  362.     nextP->prevHash = prev;
  363.   }
  364.   
  365.   thePool.release(ptr.i);
  366. }
  367. template<class T, class U>
  368. inline
  369. void 
  370. DLHashTable2<T, U>::removeAll(){
  371.   for(Uint32 i = 0; i<=mask; i++)
  372.     hashValues[i] = RNIL;
  373. }
  374. template<class T, class U>
  375. inline
  376. bool
  377. DLHashTable2<T, U>::next(Uint32 bucket, Iterator & iter) const {
  378.   while (bucket <= mask && hashValues[bucket] == RNIL) 
  379.     bucket++; 
  380.   
  381.   if (bucket > mask) {
  382.     iter.bucket = bucket;
  383.     iter.curr.i = RNIL;
  384.     return false;
  385.   }
  386.   
  387.   iter.bucket = bucket;
  388.   iter.curr.i = hashValues[bucket];
  389.   iter.curr.p = (T*)thePool.getPtr(iter.curr.i);        // cast
  390.   return true;
  391. }
  392. template<class T, class U>
  393. inline
  394. bool
  395. DLHashTable2<T, U>::seize(Ptr<T> & ptr){
  396.   Ptr<U> ptr2;
  397.   thePool.seize(ptr2);
  398.   ptr.i = ptr2.i;
  399.   ptr.p = (T*)ptr2.p;   // cast
  400.   if (ptr.p != NULL){
  401.     ptr.p->nextHash = RNIL;
  402.     ptr.p->prevHash = RNIL;
  403.     new (ptr.p) T;      // ctor
  404.   }
  405.   return !ptr.isNull();
  406. }
  407. template<class T, class U>
  408. inline
  409. void
  410. DLHashTable2<T, U>::getPtr(Ptr<T> & ptr, Uint32 i) const {
  411.   ptr.i = i;
  412.   ptr.p = (T*)thePool.getPtr(i);        // cast
  413. }
  414. template<class T, class U>
  415. inline
  416. void
  417. DLHashTable2<T, U>::getPtr(Ptr<T> & ptr) const {
  418.   Ptr<U> ptr2;
  419.   thePool.getPtr(ptr2);
  420.   ptr.i = ptr2.i;
  421.   ptr.p = (T*)ptr2.p;   // cast
  422. }
  423. template<class T, class U>
  424. inline
  425. T * 
  426. DLHashTable2<T, U>::getPtr(Uint32 i) const {
  427.   return (T*)thePool.getPtr(i); // cast
  428. }
  429. template<class T, class U>
  430. inline
  431. bool
  432. DLHashTable2<T, U>::find(Ptr<T> & ptr, const T & key) const {
  433.   const Uint32 hv = key.hashValue() & mask;  
  434.   
  435.   Uint32 i;
  436.   T * p;
  437.   i = hashValues[hv];
  438.   while(i != RNIL){
  439.     p = (T*)thePool.getPtr(i);  // cast
  440.     if(key.equal(* p)){
  441.       ptr.i = i;
  442.       ptr.p = p;
  443.       return true;
  444.     }
  445.     i = p->nextHash;
  446.   }
  447.   ptr.i = RNIL;
  448.   ptr.p = NULL;
  449.   return false;
  450. }
  451. #endif