Wm4THashTable.inl

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.0 (2006/06/28)
00016 
00017 namespace Wm4
00018 {
00019 //----------------------------------------------------------------------------
00020 template <class TKEY, class TVALUE>
00021 THashTable<TKEY,TVALUE>::THashTable (int iTableSize)
00022 {
00023     assert(iTableSize > 0);
00024 
00025     m_iTableSize = iTableSize;
00026     m_iQuantity = 0;
00027     m_iIndex = 0;
00028     m_pkItem = 0;
00029     m_apkTable = WM4_NEW HashItem*[m_iTableSize];
00030     memset(m_apkTable,0,m_iTableSize*sizeof(HashItem*));
00031     UserHashFunction = 0;
00032 }
00033 //----------------------------------------------------------------------------
00034 template <class TKEY, class TVALUE>
00035 THashTable<TKEY,TVALUE>::~THashTable ()
00036 {
00037     RemoveAll();
00038     WM4_DELETE[] m_apkTable;
00039 }
00040 //----------------------------------------------------------------------------
00041 template <class TKEY, class TVALUE>
00042 int THashTable<TKEY,TVALUE>::GetQuantity () const
00043 {
00044     return m_iQuantity;
00045 }
00046 //----------------------------------------------------------------------------
00047 template <class TKEY, class TVALUE>
00048 bool THashTable<TKEY,TVALUE>::Insert (const TKEY& rtKey,
00049     const TVALUE& rtValue)
00050 {
00051     // find hash table entry for given key
00052     int iIndex = HashFunction(rtKey);
00053     HashItem* pkItem = m_apkTable[iIndex];
00054 
00055     // search for item in list associated with key
00056     while (pkItem)
00057     {
00058         if (rtKey == pkItem->m_tKey)
00059         {
00060             // item already in hash table
00061             return false;
00062         }
00063         pkItem = pkItem->m_pkNext;
00064     }
00065 
00066     // add item to beginning of list
00067     pkItem = WM4_NEW HashItem;
00068     pkItem->m_tKey = rtKey;
00069     pkItem->m_tValue = rtValue;
00070     pkItem->m_pkNext = m_apkTable[iIndex];
00071     m_apkTable[iIndex] = pkItem;
00072     m_iQuantity++;
00073 
00074     return true;
00075 }
00076 //----------------------------------------------------------------------------
00077 template <class TKEY, class TVALUE>
00078 TVALUE* THashTable<TKEY,TVALUE>::Find (const TKEY& rtKey) const
00079 {
00080     // find hash table entry for given key
00081     int iIndex = HashFunction(rtKey);
00082     HashItem* pkItem = m_apkTable[iIndex];
00083 
00084     // search for item in list associated with key
00085     while (pkItem)
00086     {
00087         if (rtKey == pkItem->m_tKey)
00088         {
00089             // item is in hash table
00090             return &pkItem->m_tValue;
00091         }
00092         pkItem = pkItem->m_pkNext;
00093     }
00094 
00095     return 0;
00096 }
00097 //----------------------------------------------------------------------------
00098 template <class TKEY, class TVALUE>
00099 bool THashTable<TKEY,TVALUE>::Remove (const TKEY& rtKey)
00100 {
00101     // find hash table entry for given key
00102     int iIndex = HashFunction(rtKey);
00103     HashItem* pkItem = m_apkTable[iIndex];
00104 
00105     if (!pkItem)
00106     {
00107         return false;
00108     }
00109 
00110     if (rtKey == pkItem->m_tKey)
00111     {
00112         // item is at front of list, strip it off
00113         HashItem* pkSave = pkItem;
00114         m_apkTable[iIndex] = pkItem->m_pkNext;
00115         WM4_DELETE pkSave;
00116         m_iQuantity--;
00117         return true;
00118     }
00119 
00120     // search for item in list
00121     HashItem* pkPrev = pkItem;
00122     HashItem* pkCurr = pkItem->m_pkNext;
00123     while (pkCurr && rtKey != pkCurr->m_tKey)
00124     {
00125         pkPrev = pkCurr;
00126         pkCurr = pkCurr->m_pkNext;
00127     }
00128 
00129     if (pkCurr)
00130     {
00131         // found the item
00132         pkPrev->m_pkNext = pkCurr->m_pkNext;
00133         WM4_DELETE pkCurr;
00134         m_iQuantity--;
00135         return true;
00136     }
00137 
00138     return false;
00139 }
00140 //----------------------------------------------------------------------------
00141 template <class TKEY, class TVALUE>
00142 void THashTable<TKEY,TVALUE>::RemoveAll ()
00143 {
00144     if (m_iQuantity > 0)
00145     {
00146         for (int iIndex = 0; iIndex < m_iTableSize; iIndex++)
00147         {
00148             while (m_apkTable[iIndex])
00149             {
00150                 HashItem* pkSave = m_apkTable[iIndex];
00151                 m_apkTable[iIndex] = m_apkTable[iIndex]->m_pkNext;
00152                 WM4_DELETE pkSave;
00153                 if (--m_iQuantity == 0)
00154                 {
00155                     return;
00156                 }
00157             }
00158         }
00159     }
00160 }
00161 //----------------------------------------------------------------------------
00162 template <class TKEY, class TVALUE>
00163 TVALUE* THashTable<TKEY,TVALUE>::GetFirst (TKEY* ptKey) const
00164 {
00165     if (m_iQuantity > 0)
00166     {
00167         for (m_iIndex = 0; m_iIndex < m_iTableSize; m_iIndex++)
00168         {
00169             if (m_apkTable[m_iIndex])
00170             {
00171                 m_pkItem = m_apkTable[m_iIndex];
00172                 *ptKey = m_pkItem->m_tKey;
00173                 return &m_pkItem->m_tValue;
00174             }
00175         }
00176     }
00177 
00178     return 0;
00179 }
00180 //----------------------------------------------------------------------------
00181 template <class TKEY, class TVALUE>
00182 TVALUE* THashTable<TKEY,TVALUE>::GetNext (TKEY* ptKey) const
00183 {
00184     if (m_iQuantity > 0)
00185     {
00186         m_pkItem = m_pkItem->m_pkNext;
00187         if (m_pkItem)
00188         {
00189             *ptKey = m_pkItem->m_tKey;
00190             return &m_pkItem->m_tValue;
00191         }
00192         
00193         for (m_iIndex++; m_iIndex < m_iTableSize; m_iIndex++)
00194         {
00195             if (m_apkTable[m_iIndex])
00196             {
00197                 m_pkItem = m_apkTable[m_iIndex];
00198                 *ptKey = m_pkItem->m_tKey;
00199                 return &m_pkItem->m_tValue;
00200             }
00201         }
00202     }
00203 
00204     return 0;
00205 }
00206 //----------------------------------------------------------------------------
00207 template <class TKEY, class TVALUE>
00208 int THashTable<TKEY,TVALUE>::HashFunction (const TKEY& rtKey) const
00209 {
00210     if (UserHashFunction)
00211     {
00212         return (*UserHashFunction)(rtKey);
00213     }
00214 
00215     // default hash function
00216     static double s_dHashMultiplier = 0.5*(sqrt(5.0)-1.0);
00217     unsigned int uiKey;
00218     System::Memcpy(&uiKey,sizeof(unsigned int),&rtKey,sizeof(unsigned int));
00219     uiKey %= m_iTableSize;
00220     double dFraction = fmod(s_dHashMultiplier*uiKey,1.0);
00221     return (int)floor(m_iTableSize*dFraction);
00222 }
00223 //----------------------------------------------------------------------------
00224 } //namespace Wm4

Generated on Wed Nov 23 19:01:09 2011 for FreeCAD by  doxygen 1.6.1