00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef TA_HASHTABLE_H
00014 #define TA_HASHTABLE_H
00015
00016 #ifndef TA_TYPES_H
00017 #include "Types.h"
00018 #endif // TA_TYPES_H
00019
00020 #ifndef TA_STRING_H
00021 #include "String.h"
00022 #endif // TA_STRING_H
00023
00024 #ifndef TA_LIST_H
00025 #include "List.h"
00026 #endif // TA_LIST_H
00027
00028 namespace TA
00029 {
00030
00031 template <class Type>
00032 class TACOMMON_CLASS HashTable
00033 {
00034 public:
00035 class Item
00036 {
00037 public:
00038 Item() { m_pData = 0; }
00039 ~Item() {}
00040
00041 Type* GetData() { return m_pData; }
00042 const Type* GetData() const { return m_pData; }
00043 void SetData(Type* pData) { m_pData = pData; }
00044
00045 private:
00046 friend HashTable;
00047 Type* m_pData;
00048 String m_strString;
00049 };
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 HashTable();
00102 ~HashTable();
00103
00104 void Initialise(int nHashSize);
00105 void Finalise();
00106
00107 Item& CreateItem(const Char* szString);
00108 Item* GetItemIfExists(const Char* szString);
00109 void RemoveItem(const Char* szString);
00110
00111
00112
00113
00114 void Traverse(void (TAC_CALL *pCallBack)(Item& item, void* pCallBackData), void* pCallBackData);
00115
00116
00117
00118
00119
00120
00121
00122 private:
00123
00124 int m_nHashSize;
00125 List<Item>* m_pHashTable;
00126
00127 int CalculateHashValue(const Char * szString);
00128
00129 };
00130
00131
00132
00133 template <class Type>
00134 HashTable<Type>::HashTable()
00135 {
00136 m_pHashTable = 0;
00137 }
00138
00139
00140
00141 template <class Type>
00142 HashTable<Type>::~HashTable()
00143 {
00144 Finalise();
00145 }
00146
00147
00148
00149 template <class Type>
00150 void HashTable<Type>::Initialise(int nHashSize)
00151 {
00152 m_nHashSize = nHashSize;
00153 if (m_pHashTable != 0)
00154 {
00155 TA_ASSERT(0);
00156 Finalise();
00157 }
00158 TA_MEMORY_MGR_NEW_ARRAY(m_pHashTable, List<Item>, m_nHashSize);
00159 }
00160
00161
00162
00163 template <class Type>
00164 void HashTable<Type>::Finalise()
00165 {
00166 if (m_pHashTable)
00167 {
00168 TA_MEMORY_MGR_DELETE_ARRAY(m_pHashTable, List<Item>);
00169 m_pHashTable = 0;
00170 }
00171 m_nHashSize = 0;
00172 }
00173
00174
00175
00176 template <class Type>
00177 typename HashTable<Type>::Item& HashTable<Type>::CreateItem(const Char* szString)
00178 {
00179
00180 int nHashValue = CalculateHashValue(szString);
00181 List<Item>& list = m_pHashTable[nHashValue];
00182 for (List<Item>::Iterator it = list.GetIterator(); !it.AtEnd(); ++it)
00183 {
00184 Item& item = *it;
00185 if (item.m_strString == szString)
00186 return item;
00187 }
00188 Item& item = list.Append();
00189 item.m_strString = szString;
00190 return item;
00191 }
00192
00193
00194
00195 template <class Type>
00196 typename HashTable<Type>::Item* HashTable<Type>::GetItemIfExists(const Char* szString)
00197 {
00198
00199 int nHashValue = CalculateHashValue(szString);
00200 List<Item>& list = m_pHashTable[nHashValue];
00201 for (List<Item>::Iterator it = list.GetIterator(); !it.AtEnd(); ++it)
00202 {
00203 Item& item = *it;
00204 if (item.m_strString == szString)
00205 return &item;
00206 }
00207 return 0;
00208 }
00209
00210
00211
00212 template <class Type>
00213 void HashTable<Type>::RemoveItem(const Char* szString)
00214 {
00215 int nHashValue = CalculateHashValue(szString);
00216 List<Item>& list = m_pHashTable[nHashValue];
00217 for (List<Item>::Iterator it = list.GetIterator(); !it.AtEnd(); ++it)
00218 {
00219 Item& item = *it;
00220 if (item.m_strString == szString)
00221 {
00222 list.Remove(&item);
00223 return;
00224 }
00225 }
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 template <class Type>
00241 void HashTable<Type>::Traverse(void (TAC_CALL *pCallBack)(Item& item, void* pCallBackData), void* pCallBackData)
00242 {
00243 if (!pCallBack)
00244 return;
00245 for (int nIndex = 0; nIndex < m_nHashSize; nIndex++)
00246 {
00247 List<Item>& list = m_pHashTable[nIndex];
00248 for (List<Item>::Iterator it = list.GetIterator(); !it.AtEnd(); ++it)
00249 {
00250 Item& item = *it;
00251 pCallBack(item, pCallBackData);
00252 }
00253 }
00254 }
00255
00256
00257
00258 template <class Type>
00259 int HashTable<Type>::CalculateHashValue(const Char * szString)
00260 {
00261
00262 for (int nHashValue = 0; *szString != '\0'; szString++)
00263 nHashValue = ((nHashValue << 8) + *szString) % m_nHashSize;
00264 return nHashValue;
00265 }
00266
00267 };
00268
00269 #endif // TA_HASHTABLE_H
© Copyright 2004-2006 TRUE AXIS PTY LTD Australia. All rights reserved.