00001
00024 #ifndef INC_MI32_MIHASH_H
00025 #define INC_MI32_MIHASH_H
00026
00027 #ifndef INC_MI32_MILIST_H
00028 #include <mi32/milist.h>
00029 #endif
00030
00037
00038 template <typename _ITEMTYPE> class MIHASH {
00039 private:
00040 #ifndef GENERATING_DOXYGEN_OUTPUT
00041 typedef MILIST<_ITEMTYPE> HASHBUCKET;
00042 #endif // GENERATING_DOXYGEN_OUTPUT
00043
00044 public:
00045
00046 class ITERATOR;
00047 class CONST_ITERATOR;
00048 friend class CONST_ITERATOR;
00049 friend class ITERATOR;
00050
00051 class CONST_ITERATOR {
00052 public:
00054 CONST_ITERATOR (
00055 ) :
00056 m_Hash(0),
00057 m_BucketIndex(0)
00058 { }
00059
00061 CONST_ITERATOR (
00062 const ITERATOR& rhs
00063 ) :
00064 m_Hash(rhs.m_Hash),
00065 m_BucketIndex(rhs.m_BucketIndex),
00066 m_Item(rhs.m_Item)
00067 {}
00068
00070 const _ITEMTYPE& operator* (
00071 ) const {
00072 return (*m_Item);
00073 }
00074
00076 const _ITEMTYPE* operator-> (
00077 ) const {
00078 return (&**this);
00079 }
00080
00082 CONST_ITERATOR& operator++ (
00083 ) {
00084 if (m_BucketIndex < m_Hash->m_NumBuckets) {
00085 ++m_Item;
00086 while (m_Item == m_Hash->m_BucketList[m_BucketIndex].End()) {
00087 ++m_BucketIndex;
00088 if (m_BucketIndex == m_Hash->m_NumBuckets) {
00089 m_Item = m_Hash->m_BucketList[m_BucketIndex-1].End();
00090 }
00091 else {
00092 m_Item = m_Hash->m_BucketList[m_BucketIndex].Begin();
00093 }
00094 }
00095 }
00096 return (*this);
00097 }
00098
00101
00102 bool operator== (
00103 const CONST_ITERATOR& rhs
00104 ) const {
00105 return (m_Item == rhs.m_Item && m_BucketIndex == rhs.m_BucketIndex);
00106 }
00107
00108 bool operator!= (
00109 const CONST_ITERATOR& rhs
00110 ) const {
00111 return (!(*this == rhs));
00112 }
00113
00114 protected:
00115 const MIHASH<_ITEMTYPE> *const m_Hash;
00116 UINT32 m_BucketIndex;
00117 typename HASHBUCKET::ITERATOR m_Item;
00118
00120 CONST_ITERATOR (
00121 const MIHASH<_ITEMTYPE> *const hash
00122 ) :
00123 m_Hash(hash),
00124 m_BucketIndex(0),
00125 m_Item(m_Hash->m_BucketList[0].Begin())
00126 {
00127 if (m_Item == m_Hash->m_BucketList[0].End()) {
00129 operator++();
00130 }
00131 }
00132
00134 CONST_ITERATOR (
00135 const MIHASH<_ITEMTYPE> *const hash,
00136 int
00137 ) :
00138 m_Hash(hash),
00139 m_BucketIndex(m_Hash->m_NumBuckets),
00140 m_Item(m_Hash->m_BucketList[0].Begin())
00141 {}
00142
00144 CONST_ITERATOR (
00145 const MIHASH<_ITEMTYPE> *const hash,
00146 UINT32 BucketIndex,
00147 typename HASHBUCKET::ITERATOR Item
00148 ) :
00149 m_Hash(hash),
00150 m_BucketIndex(BucketIndex),
00151 m_Item(Item)
00152 { }
00153
00154 friend class MIHASH<_ITEMTYPE>;
00155 };
00156
00158 class ITERATOR : public CONST_ITERATOR {
00159 public:
00160
00162 ITERATOR (
00163 ) :
00164 CONST_ITERATOR()
00165 {}
00166
00168 _ITEMTYPE& operator* (
00169 ) const {
00170 return (*CONST_ITERATOR::m_Item);
00171 }
00172
00174 _ITEMTYPE* operator-> (
00175 ) const {
00176 return (&**this);
00177 }
00178
00180 ITERATOR& operator++ (
00181 ) {
00182 CONST_ITERATOR::operator++();
00183 return (*this);
00184 }
00185
00188
00189 bool operator== (
00190 const ITERATOR& rhs
00191 ) const {
00192 return (CONST_ITERATOR::m_Item == rhs.m_Item && CONST_ITERATOR::m_BucketIndex == rhs.m_BucketIndex);
00193 }
00194
00195 bool operator!= (
00196 const ITERATOR& rhs
00197 ) const {
00198 return (!(*this == rhs));
00199 }
00200 private:
00201 #ifndef GENERATING_DOXYGEN_OUTPUT
00203 ITERATOR (
00204 const MIHASH<_ITEMTYPE> *const hash
00205 ):
00206 CONST_ITERATOR(hash)
00207 { }
00208
00210 ITERATOR (
00211 const MIHASH<_ITEMTYPE> *const hash,
00212 int
00213 ):
00214 CONST_ITERATOR(hash,0)
00215 { }
00216
00218 ITERATOR (
00219 const MIHASH<_ITEMTYPE> *const hash,
00220 UINT32 BucketIndex,
00221 typename HASHBUCKET::ITERATOR Item
00222 ) :
00223 CONST_ITERATOR(hash, BucketIndex, Item)
00224 { }
00225
00226 friend class MIHASH<_ITEMTYPE>;
00227 #endif // GENERATING_DOXYGEN_OUTPUT
00228 };
00229
00230
00231
00232
00234 explicit MIHASH (
00235 UINT32 NumBuckets = 32
00236 ) :
00237 m_NumBuckets(NumBuckets),
00238 m_BucketList(new HASHBUCKET[NumBuckets])
00239 {}
00240
00242 MIHASH (
00243 const MIHASH& rhs
00244 ) :
00245 m_NumBuckets(rhs.m_NumBuckets),
00246 m_BucketList(new HASHBUCKET[rhs.m_NumBuckets])
00247 {
00248 for (UINT32 i = 0;(i < m_NumBuckets);++i) {
00249 m_BucketList[i] = rhs.m_BucketList[i];
00250 }
00251 }
00252
00254 ~MIHASH (
00255 ) {
00256 delete [] m_BucketList;
00257 }
00258
00259
00260
00262 void Add (
00263 const _ITEMTYPE& item
00264 ) {
00265 UINT32 HashNum = item.GetHashNumber() % m_NumBuckets;
00266 typename HASHBUCKET::CONST_ITERATOR it;
00267 for (it = m_BucketList[HashNum].Begin();(it != m_BucketList[HashNum].End());++it) {
00268 if (*it == item) break;
00269 }
00270 if (it == m_BucketList[HashNum].End()) m_BucketList[HashNum].PushBack(item);
00271 return;
00272 }
00273
00277 CONST_ITERATOR Begin (
00278 ) const {
00279 return (CONST_ITERATOR(this));
00280 }
00281
00285 ITERATOR Begin (
00286 ) {
00287 return (ITERATOR(this));
00288 }
00289
00291 void Clear (
00292 ) {
00293 for (UINT32 i = 0;(i < m_NumBuckets);++i) {
00294 m_BucketList[i].Clear();
00295 }
00296 return;
00297 }
00298
00302 CONST_ITERATOR End (
00303 ) const {
00304 return (CONST_ITERATOR(this,0));
00305 }
00306
00310 ITERATOR End (
00311 ) {
00312 return (ITERATOR(this,0));
00313 }
00314
00318 template <typename _CMP> bool Exists (
00319 const _CMP& item
00320 ) const {
00321 return (Find(item) != End());
00322 }
00323
00327 template <typename _CMP> ITERATOR Find (
00328 const _CMP& item
00329 ) {
00330 UINT32 HashNum = item.GetHashNumber() % m_NumBuckets;
00331 typename HASHBUCKET::ITERATOR it;
00332 for (it = m_BucketList[HashNum].Begin();(it != m_BucketList[HashNum].End());++it) {
00333 if (item == *it) break;
00334 }
00335 ITERATOR retval = (it != m_BucketList[HashNum].End()) ? ITERATOR(this, HashNum, it) : End();
00336 return (retval);
00337 }
00338
00342 template <typename _CMP> CONST_ITERATOR Find (
00343 const _CMP& item
00344 ) const {
00345 UINT32 HashNum = item.GetHashNumber() % m_NumBuckets;
00346 typename HASHBUCKET::ITERATOR it;
00347 for (it = m_BucketList[HashNum].Begin();(it != m_BucketList[HashNum].End());++it) {
00348 if (item == *it) break;
00349 }
00350 CONST_ITERATOR retval = (it != m_BucketList[HashNum].End()) ? CONST_ITERATOR(this, HashNum, it) : End();
00351 return (retval);
00352 }
00353
00355 void Remove (
00356 ITERATOR item
00357 ) {
00358 if (item != End()) m_BucketList[item.m_BucketIndex].Remove(item.m_Item);
00359 return;
00360 }
00361
00363 void Resize (
00364 INT32 NumBuckets
00365 ) {
00366 Clear();
00367 delete [] m_BucketList;
00368 m_BucketList = new HASHBUCKET[NumBuckets];
00369 m_NumBuckets = NumBuckets;
00370 return;
00371 }
00372
00373 private:
00374 #ifndef GENERATING_DOXYGEN_OUTPUT
00375
00376 MIHASH& operator= (
00377 const MIHASH& rhs
00378 );
00379
00380 UINT32 m_NumBuckets;
00381 HASHBUCKET *m_BucketList;
00382 #endif // GENERATING_DOXYGEN_OUTPUT
00383
00384 };
00385
00386 #endif // INC_MI32_MIHASH_H