Wm4THashSet.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>
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
00051 int iIndex = HashFunction(rtKey);
00052 HashItem* pkItem = m_apkTable[iIndex];
00053
00054
00055 while (pkItem)
00056 {
00057 if (rtKey == pkItem->m_tKey)
00058 {
00059
00060 return &pkItem->m_tKey;
00061 }
00062 pkItem = pkItem->m_pkNext;
00063 }
00064
00065
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
00079 int iIndex = HashFunction(rtKey);
00080 HashItem* pkItem = m_apkTable[iIndex];
00081
00082
00083 while (pkItem)
00084 {
00085 if (rtKey == pkItem->m_tKey)
00086 {
00087
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
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
00111 HashItem* pkSave = pkItem;
00112 m_apkTable[iIndex] = pkItem->m_pkNext;
00113 WM4_DELETE pkSave;
00114 m_iQuantity--;
00115 return true;
00116 }
00117
00118
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
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
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 }