Wm4THashSet.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>
00021 THashSet<TKEY>::THashSet (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>
00035 THashSet<TKEY>::~THashSet ()
00036 {
00037     RemoveAll();
00038     WM4_DELETE[] m_apkTable;
00039 }
00040 //----------------------------------------------------------------------------
00041 template <class TKEY>
00042 int THashSet<TKEY>::GetQuantity () const
00043 {
00044     return m_iQuantity;
00045 }
00046 //----------------------------------------------------------------------------
00047 template <class TKEY>
00048 TKEY* THashSet<TKEY>::Insert (const TKEY& rtKey)
00049 {
00050     // find hash table entry for given key
00051     int iIndex = HashFunction(rtKey);
00052     HashItem* pkItem = m_apkTable[iIndex];
00053 
00054     // search for item in list associated with key
00055     while (pkItem)
00056     {
00057         if (rtKey == pkItem->m_tKey)
00058         {
00059             // item already in hash table
00060             return &pkItem->m_tKey;
00061         }
00062         pkItem = pkItem->m_pkNext;
00063     }
00064 
00065     // add item to beginning of list
00066     pkItem = WM4_NEW HashItem;
00067     pkItem->m_tKey = rtKey;
00068     pkItem->m_pkNext = m_apkTable[iIndex];
00069     m_apkTable[iIndex] = pkItem;
00070     m_iQuantity++;
00071 
00072     return &pkItem->m_tKey;
00073 }
00074 //----------------------------------------------------------------------------
00075 template <class TKEY>
00076 TKEY* THashSet<TKEY>::Get (const TKEY& rtKey) const
00077 {
00078     // find hash table entry for given key
00079     int iIndex = HashFunction(rtKey);
00080     HashItem* pkItem = m_apkTable[iIndex];
00081 
00082     // search for item in list associated with key
00083     while (pkItem)
00084     {
00085         if (rtKey == pkItem->m_tKey)
00086         {
00087             // item is in hash table
00088             return &pkItem->m_tKey;
00089         }
00090         pkItem = pkItem->m_pkNext;
00091     }
00092 
00093     return 0;
00094 }
00095 //----------------------------------------------------------------------------
00096 template <class TKEY>
00097 bool THashSet<TKEY>::Remove (const TKEY& rtKey)
00098 {
00099     // find hash table entry for given key
00100     int iIndex = HashFunction(rtKey);
00101     HashItem* pkItem = m_apkTable[iIndex];
00102 
00103     if (!pkItem)
00104     {
00105         return false;
00106     }
00107 
00108     if (rtKey == pkItem->m_tKey)
00109     {
00110         // item is at front of list, strip it off
00111         HashItem* pkSave = pkItem;
00112         m_apkTable[iIndex] = pkItem->m_pkNext;
00113         WM4_DELETE pkSave;
00114         m_iQuantity--;
00115         return true;
00116     }
00117 
00118     // search for item in list
00119     HashItem* pkPrev = pkItem;
00120     HashItem* pkCurr = pkItem->m_pkNext;
00121     while (pkCurr && rtKey != pkCurr->m_tKey)
00122     {
00123         pkPrev = pkCurr;
00124         pkCurr = pkCurr->m_pkNext;
00125     }
00126 
00127     if (pkCurr)
00128     {
00129         // found the item
00130         pkPrev->m_pkNext = pkCurr->m_pkNext;
00131         WM4_DELETE pkCurr;
00132         m_iQuantity--;
00133         return true;
00134     }
00135 
00136     return false;
00137 }
00138 //----------------------------------------------------------------------------
00139 template <class TKEY>
00140 void THashSet<TKEY>::RemoveAll ()
00141 {
00142     if (m_iQuantity > 0)
00143     {
00144         for (int iIndex = 0; iIndex < m_iTableSize; iIndex++)
00145         {
00146             while (m_apkTable[iIndex])
00147             {
00148                 HashItem* pkSave = m_apkTable[iIndex];
00149                 m_apkTable[iIndex] = m_apkTable[iIndex]->m_pkNext;
00150                 WM4_DELETE pkSave;
00151                 if (--m_iQuantity == 0)
00152                 {
00153                     return;
00154                 }
00155             }
00156         }
00157     }
00158 }
00159 //----------------------------------------------------------------------------
00160 template <class TKEY>
00161 TKEY* THashSet<TKEY>::GetFirst () const
00162 {
00163     if (m_iQuantity > 0)
00164     {
00165         for (m_iIndex = 0; m_iIndex < m_iTableSize; m_iIndex++)
00166         {
00167             if (m_apkTable[m_iIndex])
00168             {
00169                 m_pkItem = m_apkTable[m_iIndex];
00170                 return &m_pkItem->m_tKey;
00171             }
00172         }
00173     }
00174 
00175     return 0;
00176 }
00177 //----------------------------------------------------------------------------
00178 template <class TKEY>
00179 TKEY* THashSet<TKEY>::GetNext () const
00180 {
00181     if (m_iQuantity > 0)
00182     {
00183         m_pkItem = m_pkItem->m_pkNext;
00184         if (m_pkItem)
00185         {
00186             return &m_pkItem->m_tKey;
00187         }
00188         
00189         for (m_iIndex++; m_iIndex < m_iTableSize; m_iIndex++)
00190         {
00191             if (m_apkTable[m_iIndex])
00192             {
00193                 m_pkItem = m_apkTable[m_iIndex];
00194                 return &m_pkItem->m_tKey;
00195             }
00196         }
00197     }
00198 
00199     return 0;
00200 }
00201 //----------------------------------------------------------------------------
00202 template <class TKEY>
00203 int THashSet<TKEY>::HashFunction (const TKEY& rtKey) const
00204 {
00205     if (UserHashFunction)
00206     {
00207         return (*UserHashFunction)(rtKey);
00208     }
00209 
00210     // default hash function
00211     static double s_dHashMultiplier = 0.5*(sqrt(5.0)-1.0);
00212     unsigned int uiKey;
00213     System::Memcpy(&uiKey,sizeof(unsigned int),&rtKey,sizeof(unsigned int));
00214     uiKey %= m_iTableSize;
00215     double dFraction = fmod(s_dHashMultiplier*uiKey,1.0);
00216     return (int)floor(m_iTableSize*dFraction);
00217 }
00218 //----------------------------------------------------------------------------
00219 } //namespace Wm4

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