Wm4THashTable.inl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00052 int iIndex = HashFunction(rtKey);
00053 HashItem* pkItem = m_apkTable[iIndex];
00054
00055
00056 while (pkItem)
00057 {
00058 if (rtKey == pkItem->m_tKey)
00059 {
00060
00061 return false;
00062 }
00063 pkItem = pkItem->m_pkNext;
00064 }
00065
00066
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
00081 int iIndex = HashFunction(rtKey);
00082 HashItem* pkItem = m_apkTable[iIndex];
00083
00084
00085 while (pkItem)
00086 {
00087 if (rtKey == pkItem->m_tKey)
00088 {
00089
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
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
00113 HashItem* pkSave = pkItem;
00114 m_apkTable[iIndex] = pkItem->m_pkNext;
00115 WM4_DELETE pkSave;
00116 m_iQuantity--;
00117 return true;
00118 }
00119
00120
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
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
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 }