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

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