00001
00002
00003
00004
00005
00006
00007 #ifndef _hash_h_
00008 #define _hash_h_
00009
00010 #include <iostream>
00011
00012 #ifndef NULL
00013 #define NULL 0
00014 #endif
00015
00016
00017
00018 namespace CVCL {
00019 using std::pair;
00020
00021 template <class _Key>
00022 static size_t hash(_Key e) { return 1;}
00023 template <class _Key>
00024 static size_t equal_to(_Key x, _Key y) { return x==y;}
00025
00026
00027 const int HASH_TABLE_SIZE = 1024;
00028 const int HASH_TABLE_GROW_THRESHOLD = 1;
00029 const int HASH_TABLE_GROW_FACTOR = 2;
00030 typedef void *void_pointer;
00031
00032 template <class _Key, class _Data> class Hash_Table;
00033 template <class _Key, class _Data> class Hash_Entry;
00034 template <class _Key, class _Data> class Hash_Ptr;
00035
00036
00037 template <class _Key, class _Data>
00038 struct _Hashtable_iterator;
00039
00040 template <class _Key, class _Data>
00041 struct _Hashtable_const_iterator;
00042
00043 template <class _Key, class _Data>
00044 struct _Hashtable_iterator {
00045 typedef Hash_Table<_Key,_Data>
00046 _Hashtable;
00047 typedef _Hashtable_iterator<_Key, _Data>
00048 iterator;
00049 typedef _Hashtable_const_iterator<_Key, _Data>
00050 const_iterator;
00051 typedef Hash_Entry<_Key, _Data> _Node;
00052
00053
00054
00055
00056
00057 typedef pair<const _Key,_Data>& reference;
00058 typedef pair<const _Key,_Data>* pointer;
00059
00060 _Node* _M_cur;
00061 _Hashtable* _M_ht;
00062
00063 _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
00064 : _M_cur(__n), _M_ht(__tab) {}
00065 _Hashtable_iterator() {}
00066 reference operator*() const { return _M_cur->Val(); }
00067 pointer operator->() const { return &(operator*()); }
00068 iterator& operator++(){
00069
00070 _M_cur = _M_cur->Next();
00071
00072
00073 return *this;
00074 }
00075
00076 bool operator==(const iterator& __it) const
00077 { return _M_cur == __it._M_cur; }
00078 bool operator!=(const iterator& __it) const
00079 { return _M_cur != __it._M_cur; }
00080 };
00081
00082
00083 template <class _Key, class _Data>
00084 struct _Hashtable_const_iterator {
00085 typedef Hash_Table<_Key,_Data>
00086 _Hashtable;
00087 typedef _Hashtable_iterator<_Key,_Data> iterator;
00088 typedef _Hashtable_const_iterator<_Key,_Data>
00089 const_iterator;
00090 typedef Hash_Entry<_Key,_Data> _Node;
00091
00092
00093
00094
00095
00096 typedef const pair<const _Key,_Data>& reference;
00097 typedef const pair<const _Key,_Data>* pointer;
00098
00099 const _Node* _M_cur;
00100 const _Hashtable* _M_ht;
00101
00102 _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
00103 : _M_cur(__n), _M_ht(__tab) {
00104
00105 }
00106 _Hashtable_const_iterator() {}
00107 _Hashtable_const_iterator(const iterator& __it)
00108 : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {}
00109 reference operator*() const {
00110
00111 pair<_Key,_Data> tmp(_M_cur->Val());
00112
00113 return tmp;
00114 }
00115 pointer operator->() const {
00116 return &(operator*()); }
00117 const_iterator& operator++(){
00118
00119
00120 _M_cur = _M_cur->Next();
00121
00122
00123 return *this;
00124 }
00125
00126 bool operator==(const const_iterator& __it) const
00127 {
00128 return _M_cur == __it._M_cur; }
00129 bool operator!=(const const_iterator& __it) const
00130 {
00131 return _M_cur != __it._M_cur; }
00132 };
00133
00134
00135
00136
00137
00138
00139 template <class _Key, class _Data>
00140 class Hash_Entry {
00141
00142 private:
00143 _Key _key;
00144 _Data _data;
00145 pair<const _Key,_Data> _val;
00146 Hash_Entry *_next;
00147
00148
00149 Hash_Entry(const _Key &key, const _Data &data) :
00150 _key(key), _data(data), _val(make_pair(key,data)), _next(NULL) {}
00151 Hash_Entry(const Hash_Entry &rhs) :
00152 _key(rhs._key), _data(rhs._data), _val(make_pair(rhs._key,rhs._data)), _next(NULL) {}
00153 ~Hash_Entry() {}
00154 friend class Hash_Table<_Key, _Data>;
00155
00156 public:
00157 Hash_Entry* Next() const { return _next; }
00158 _Key Key() const { return _key; }
00159 _Data& Data() { return _data; }
00160 pair<const _Key,_Data> Val() const {
00161
00162 pair<const _Key,_Data> val1 = make_pair(_key,_data);
00163
00164 return val1;}
00165 bool operator==(const Hash_Entry he){
00166 if( (_key == he.Key()) && (_data == he.Data()))
00167 return true;
00168 else
00169 return false;
00170 }
00171 bool operator!=(const Hash_Entry he){
00172 if( (_key == he.Key()) && (_data == he.Data()))
00173 return false;
00174 else
00175 return true;
00176 }
00177
00178
00179 void Print();
00180
00181 };
00182
00183
00184
00185
00186
00187 template <class _Key, class _Data>
00188 class Hash_Table {
00189
00190 private:
00191 Hash_Entry<_Key, _Data> **_hashTbl;
00192
00193 size_t (*_hashFunc)(const _Key);
00194
00195 size_t (*_matchFunc)(const _Key, const _Key);
00196 int _size;
00197 int _growThreshold;
00198 int _growFactor;
00199 int _numEntries;
00200 Hash_Entry<_Key, _Data>** Find_Hash_Entry(const _Key&) const;
00201 void Copy(const Hash_Table &rhs);
00202 void Resize(int size);
00203 void Destroy();
00204 friend class Hash_Ptr<_Key, _Data>;
00205
00206
00207 public:
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 Hash_Table(size_t (*hashFunction)(const _Key),
00218 size_t (*matchFunc)(const _Key, const _Key),
00219 int size = HASH_TABLE_SIZE, int threshold = HASH_TABLE_GROW_THRESHOLD,
00220 int factor = HASH_TABLE_GROW_FACTOR);
00221 Hash_Table(const Hash_Table &hash) { Copy(hash); }
00222 ~Hash_Table() { Destroy(); }
00223 int Insert(_Key key, _Data data);
00224 int Delete(_Key key);
00225 void clear();
00226 Hash_Table& operator= (const Hash_Table &rhs);
00227 _Data* Fetch(_Key key);
00228 _Data& operator[] (_Key key);
00229
00230
00231 size_t size() const { return _numEntries; }
00232 bool empty() const { return size() == 0; }
00233 void erase(_Key key);
00234 int count(_Key key) const;
00235 typedef _Hashtable_iterator<_Key, _Data>
00236 iterator;
00237 typedef _Hashtable_const_iterator<_Key, _Data>
00238 const_iterator;
00239 friend struct
00240 _Hashtable_iterator<_Key, _Data>;
00241 friend struct
00242 _Hashtable_const_iterator<_Key, _Data>;
00243
00244
00245
00246 void Print();
00247
00248
00249 const_iterator begin() const{
00250 if (size()>0)
00251 return const_iterator(_hashTbl[0], this);
00252 else
00253 return end();
00254 }
00255
00256 const_iterator end() const{ return const_iterator(0, this); }
00257 const_iterator find(const _Key& key) const{
00258
00259 return const_iterator(*Find_Hash_Entry(key), this);
00260 }
00261 template<class InputIterator>
00262 void insert(InputIterator l, InputIterator r);
00263 };
00264
00265
00266
00267
00268
00269 template <class _Key, class _Data>
00270 class Hash_Ptr {
00271
00272 private:
00273 Hash_Table<_Key, _Data> *_hash;
00274 int _index;
00275 Hash_Entry<_Key, _Data> *_hashEntry;
00276 void Set_Next_Hash_Entry();
00277
00278 public:
00279 Hash_Ptr() : _hash(0), _index(0), _hashEntry(0) {}
00280 Hash_Ptr(Hash_Table<_Key, _Data> *hash) :
00281 _hash(hash), _index(0), _hashEntry(hash->_hashTbl[0])
00282 { if (_hashEntry == NULL) Set_Next_Hash_Entry(); }
00283 Hash_Ptr(const Hash_Table<_Key, _Data> *hash) :
00284 _hash((Hash_Table<_Key, _Data>*)hash), _index(0),
00285 _hashEntry(hash->_hashTbl[0])
00286 { if (_hashEntry == NULL) Set_Next_Hash_Entry(); }
00287 Hash_Entry<_Key, _Data>* operator-> () { return _hashEntry; }
00288 Hash_Entry<_Key, _Data>& operator* ()
00289 {
00290 return *_hashEntry; }
00291 operator void_pointer() const { return void_pointer(_hashEntry); }
00292 int Null() const { return _hashEntry == NULL; }
00293 void operator++ () { Set_Next_Hash_Entry(); }
00294 void Reset(Hash_Table<_Key, _Data> *hash)
00295 { *this = Hash_Ptr(hash); }
00296 };
00297
00298
00299
00300
00301
00302 template <class _Key, class _Data>
00303 Hash_Table<_Key, _Data>::Hash_Table
00304
00305 (size_t (*hashFunc)(const _Key), size_t (*matchFunc)(const _Key, const _Key),
00306 int size, int threshold, int factor)
00307 : _hashFunc(hashFunc), _matchFunc(matchFunc), _size(size),
00308 _growThreshold(threshold), _growFactor(factor), _numEntries(0)
00309 {
00310
00311
00312
00313
00314 _hashTbl = new Hash_Entry<_Key, _Data> *[_size];
00315 for(int i=0; i<_size; i++)
00316 _hashTbl[i] = NULL;
00317 }
00318
00319
00320
00321
00322
00323 template <class _Key, class _Data>
00324 void Hash_Table<_Key, _Data>::Destroy()
00325 {
00326 for (int i=0; i<_size; i++) {
00327 Hash_Entry<_Key, _Data> *tmp = _hashTbl[i];
00328
00329 while(tmp != NULL) {
00330 Hash_Entry<_Key, _Data> *next = tmp->_next;
00331 delete tmp;
00332 tmp = next;
00333 }
00334 }
00335
00336 delete [] _hashTbl;
00337 }
00338
00339
00340
00341
00342
00343 template <class _Key, class _Data>
00344 void Hash_Table<_Key, _Data>::Copy(const Hash_Table<_Key, _Data> &rhs)
00345 {
00346 _hashFunc = rhs._hashFunc;
00347 _matchFunc = rhs._matchFunc;
00348 _numEntries = rhs._numEntries;
00349 _size = rhs._size;
00350 _growThreshold = rhs._growThreshold;
00351 _growFactor = rhs._growFactor;
00352 _hashTbl = new Hash_Entry<_Key, _Data> *[rhs._size];
00353
00354 for (int i=0; i<rhs._size; i++) {
00355 Hash_Entry<_Key, _Data> *tmp = rhs._hashTbl[i];
00356 Hash_Entry<_Key, _Data> **copy = &(_hashTbl[i] = NULL);
00357
00358 while(tmp != NULL) {
00359 *copy = new Hash_Entry<_Key, _Data>(*tmp);
00360 copy = &(*copy)->_next;
00361 tmp = tmp->_next;
00362 }
00363 }
00364 }
00365
00366
00367
00368
00369
00370 template <class _Key, class _Data>
00371 void Hash_Table<_Key, _Data>::Resize(int size)
00372 {
00373 Hash_Table<_Key, _Data> tmp(_hashFunc, _matchFunc, size);
00374
00375 Hash_Ptr<_Key, _Data> ptr(this);
00376 for (;!ptr.Null(); ++ptr) {
00377 _Key key = ptr->Key();
00378 tmp.Insert(key, ptr->Data());
00379 }
00380
00381 Destroy();
00382 Copy(tmp);
00383 }
00384
00385
00386
00387
00388
00389 template <class _Key, class _Data>
00390 Hash_Table<_Key, _Data>& Hash_Table<_Key, _Data>::operator=
00391 (const Hash_Table<_Key, _Data> &rhs)
00392 {
00393 if (this != &rhs) {
00394 Destroy();
00395 Copy(rhs);
00396 }
00397
00398 return *this;
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408 template <class _Key, class _Data>
00409 Hash_Entry<_Key, _Data>**
00410 Hash_Table<_Key, _Data>::Find_Hash_Entry(const _Key& key) const
00411 {
00412 int index = (*_hashFunc)(key) % _size;
00413
00414
00415
00416 Hash_Entry<_Key, _Data>** link = &_hashTbl[index];
00417 while (*link != NULL && !_matchFunc((*link)->_key, key))
00418 link = &((*link)->_next);
00419 return link;
00420 }
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 template <class _Key, class _Data>
00431 int Hash_Table<_Key, _Data>::Insert(_Key key, _Data data)
00432 {
00433 if (_numEntries>_size*_growThreshold)
00434 Resize(_size*_growFactor);
00435
00436 Hash_Entry<_Key, _Data>* hash_entry =
00437 new Hash_Entry<_Key, _Data>(key, data);
00438 Hash_Entry<_Key, _Data>** link = Find_Hash_Entry(key);
00439
00440 if (*link != NULL) {
00441 delete hash_entry;
00442 return 1;
00443 }
00444
00445 _numEntries++;
00446 *link = hash_entry;
00447 return 0;
00448 }
00449
00450 template<class InputIterator>
00451 void insert(InputIterator l, InputIterator r) {
00452 for(; l!=r; ++l) {
00453 Insert((*l).first, (*l).second);
00454 }
00455 }
00456
00457
00458
00459
00460
00461
00462
00463 template <class _Key, class _Data>
00464 int Hash_Table<_Key, _Data>::Delete(_Key key)
00465 {
00466 Hash_Entry<_Key, _Data>** link = Find_Hash_Entry(key);
00467 Hash_Entry<_Key, _Data>* tmp;
00468
00469 if (*link == NULL)
00470 return 1;
00471
00472 _numEntries--;
00473 tmp = (*link);
00474 *link = (*link)->_next;
00475 delete tmp;
00476 return 0;
00477 }
00478
00479 template <class _Key, class _Data>
00480 void Hash_Table<_Key, _Data>::erase(_Key key){
00481 Hash_Entry<_Key, _Data>** link = Find_Hash_Entry(key);
00482 Hash_Entry<_Key, _Data>* tmp;
00483
00484 if (*link == NULL)
00485 return;
00486
00487 _numEntries--;
00488 tmp = (*link);
00489 *link = (*link)->_next;
00490 delete tmp;
00491 return;
00492 }
00493
00494
00495
00496
00497
00498
00499 template <class _Key, class _Data>
00500 void Hash_Table<_Key, _Data>::clear()
00501 {
00502 for (int i=0; i<_size; i++) {
00503 Hash_Entry<_Key, _Data> *tmp = _hashTbl[i];
00504 _hashTbl[i] = NULL;
00505
00506 while(tmp != NULL) {
00507 Hash_Entry<_Key, _Data> *next = tmp->_next;
00508 delete tmp;
00509 tmp = next;
00510 }
00511 }
00512 _numEntries = 0;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522 template <class _Key, class _Data>
00523 _Data* Hash_Table<_Key, _Data>::Fetch(_Key key)
00524 {
00525 Hash_Entry<_Key, _Data>** link = Find_Hash_Entry(key);
00526 return (*link) ? &(*link)->Data() : (_Data *)NULL;
00527 }
00528
00529 template <class _Key, class _Data>
00530 int Hash_Table<_Key, _Data>::count(_Key key) const{
00531 Hash_Entry<_Key, _Data>** link = Find_Hash_Entry(key);
00532 return (*link) ? 1 : 0;
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 template <class _Key, class _Data>
00549 _Data& Hash_Table<_Key, _Data>::operator[](_Key key)
00550 {
00551 _Data* result = Fetch(key);
00552 if (result) return *result;
00553 else {
00554 _Data data;
00555
00556 if (_numEntries>_size*_growThreshold)
00557 Resize(_size*_growFactor);
00558
00559 Hash_Entry<_Key, _Data>* hash_entry =
00560 new Hash_Entry<_Key, _Data>(key, data);
00561
00562 Hash_Entry<_Key, _Data>** link = Find_Hash_Entry(key);
00563
00564
00565
00566 _numEntries++;
00567 *link = hash_entry;
00568
00569
00570 return (hash_entry->Data());
00571 }
00572 }
00573
00574
00575
00576
00577 template <class _Key, class _Data>
00578 void Hash_Ptr<_Key, _Data>::Set_Next_Hash_Entry()
00579 {
00580 if (_hashEntry != NULL && _hashEntry->Next() != NULL) {
00581 _hashEntry = _hashEntry->Next();
00582 return;
00583 }
00584
00585 while (++_index < _hash->_size)
00586 if (_hash->_hashTbl[_index] != NULL) {
00587 _hashEntry = _hash->_hashTbl[_index];
00588 return;
00589 }
00590
00591 _hashEntry = NULL;
00592 }
00593
00594
00595 template <class _Key, class _Data>
00596 void HashUpdateIntData(Hash_Table<_Key, _Data>& t, _Key key, _Data i)
00597 {
00598 _Data *tmp = t.Fetch(key);
00599 if (tmp) *tmp = *tmp + i;
00600 else t.Insert(key, i);
00601 }
00602
00603
00604 #ifdef DEBUG
00605
00606
00607
00608 template <class _Key, class _Data>
00609 void Hash_Entry<_Key, _Data>::Print()
00610 {
00611 std::cout << "key: \"" << Key() << "\" data: " << Data() << '\n';
00612 }
00613
00614
00615
00616
00617
00618 template <class _Key, class _Data>
00619 void Hash_Table<_Key, _Data>::Print()
00620 {
00621 for (Hash_Ptr<_Key, _Data> ptr(this); !ptr.Null(); ++ptr)
00622 ptr->Print();
00623 }
00624 #endif
00625
00626 }
00627
00628 #endif