diff --git a/common/hashmap.h b/common/hashmap.h index 842296db991..5e0b5b6c594 100644 --- a/common/hashmap.h +++ b/common/hashmap.h @@ -56,7 +56,7 @@ #include "common/str.h" #include "common/util.h" -namespace Common { +namespace Common { typedef Common::String String; @@ -71,6 +71,30 @@ struct Hash { } }; +template <> +struct Hash { + uint operator()(const char *s) const { + return hashit(s); + } +}; + +// data structure used by HashMap internally to keep +// track of what's mapped to what. +template +struct BaseNode { + Key _key; + Val _value; + BaseNode() {} + BaseNode(const Key &key) : _key(key) {} +}; + +template +struct BaseNode { + char *_key; + Val _value; + BaseNode() {assert(0);} + BaseNode(const char *key) { printf("%s\n", key); _key = (char *)malloc(strlen(key)+1); strcpy(_key, key); } +}; // The table sizes ideally are primes. We use a helper function to find // suitable table sizes. @@ -95,23 +119,14 @@ uint nextTableSize(uint x); * triggered instead. Hence if you are not sure whether a key is contained in * the map, use contains() first to check for its presence. */ -template , class EqualFunc = EqualTo > +template , class EqualFunc = EqualTo, class BaseNodeFunc = BaseNode > class HashMap { private: #if defined (_WIN32_WCE) || defined (_MSC_VER) || defined (__SYMBIAN32__) || defined (PALMOS_MODE) //FIXME evc4, msvc6,msvc7 & GCC 2.9x doesn't like it as private member public: #endif - // data structure used by HashMap internally to keep - // track of what's mapped to what. - struct BaseNode { - Key _key; - Val _value; - BaseNode() {} - BaseNode(const Key &key) : _key(key) {} - }; - - BaseNode **_arr; // hashtable of size arrsize. + BaseNodeFunc **_arr; // hashtable of size arrsize. uint _arrsize, _nele; HashFunc _hash; @@ -126,16 +141,16 @@ public: public: class const_iterator { - typedef const HashMap * hashmap_t; - friend class HashMap; + typedef const HashMap * hashmap_t; + friend class HashMap; protected: hashmap_t _hashmap; uint _idx; const_iterator(uint idx, hashmap_t hashmap) : _idx(idx), _hashmap(hashmap) {} - const BaseNode *deref() const { + const BaseNodeFunc *deref() const { assert(_hashmap != 0); - BaseNode *node = _hashmap->_arr[_idx]; + BaseNodeFunc *node = _hashmap->_arr[_idx]; assert(node != 0); return node; } @@ -143,8 +158,8 @@ public: public: const_iterator() : _idx(0), _hashmap(0) {} - const BaseNode &operator *() const { return *deref(); } - const BaseNode *operator->() const { return deref(); } + const BaseNodeFunc &operator *() const { return *deref(); } + const BaseNodeFunc *operator->() const { return deref(); } bool operator ==(const const_iterator &iter) const { return _idx == iter._idx && _hashmap == iter._hashmap; } bool operator !=(const const_iterator &iter) const { return !(*this == iter); } const_iterator operator ++() { @@ -193,6 +208,13 @@ public: return end(); } + const_iterator find(const char *key) const { + uint ctr = lookup(key); + if (_arr[ctr]) + return const_iterator(ctr, this); + return end(); + } + // TODO: insert() method? @@ -204,12 +226,12 @@ public: //------------------------------------------------------- // HashMap functions -template -HashMap::HashMap() { +template +HashMap::HashMap() { _arrsize = nextTableSize(0); - _arr = new BaseNode *[_arrsize]; + _arr = new BaseNodeFunc *[_arrsize]; assert(_arr != NULL); - memset(_arr, 0, _arrsize * sizeof(BaseNode *)); + memset(_arr, 0, _arrsize * sizeof(BaseNodeFunc *)); _nele = 0; @@ -219,8 +241,8 @@ HashMap::HashMap() { #endif } -template -HashMap::~HashMap() { +template +HashMap::~HashMap() { uint ctr; for (ctr = 0; ctr < _arrsize; ctr++) @@ -230,8 +252,8 @@ HashMap::~HashMap() { delete[] _arr; } -template -void HashMap::clear(bool shrinkArray) { +template +void HashMap::clear(bool shrinkArray) { for (uint ctr = 0; ctr < _arrsize; ctr++) { if (_arr[ctr] != NULL) { delete _arr[ctr]; @@ -243,18 +265,18 @@ void HashMap::clear(bool shrinkArray) { delete[] _arr; _arrsize = nextTableSize(0); - _arr = new BaseNode *[_arrsize]; + _arr = new BaseNodeFunc *[_arrsize]; assert(_arr != NULL); - memset(_arr, 0, _arrsize * sizeof(BaseNode *)); + memset(_arr, 0, _arrsize * sizeof(BaseNodeFunc *)); } _nele = 0; } -template -void HashMap::expand_array(uint newsize) { +template +void HashMap::expand_array(uint newsize) { assert(newsize > _arrsize); - BaseNode **old_arr; + BaseNodeFunc **old_arr; uint old_arrsize, old_nele, ctr, dex; old_nele = _nele; @@ -263,9 +285,9 @@ void HashMap::expand_array(uint newsize) { // allocate a new array _arrsize = newsize; - _arr = new BaseNode *[_arrsize]; + _arr = new BaseNodeFunc *[_arrsize]; assert(_arr != NULL); - memset(_arr, 0, _arrsize * sizeof(BaseNode *)); + memset(_arr, 0, _arrsize * sizeof(BaseNodeFunc *)); _nele = 0; @@ -295,8 +317,8 @@ void HashMap::expand_array(uint newsize) { return; } -template -int HashMap::lookup(const Key &key) const { +template +int HashMap::lookup(const Key &key) const { uint ctr = _hash(key) % _arrsize; while (_arr[ctr] != NULL && !_equal(_arr[ctr]->_key, key)) { @@ -317,18 +339,18 @@ int HashMap::lookup(const Key &key) const { return ctr; } -template -bool HashMap::contains(const Key &key) const { +template +bool HashMap::contains(const Key &key) const { uint ctr = lookup(key); return (_arr[ctr] != NULL); } -template -Val &HashMap::operator [](const Key &key) { +template +Val &HashMap::operator [](const Key &key) { uint ctr = lookup(key); if (_arr[ctr] == NULL) { - _arr[ctr] = new BaseNode(key); + _arr[ctr] = new BaseNodeFunc(key); _nele++; // Keep the load factor below 75%. @@ -341,20 +363,20 @@ Val &HashMap::operator [](const Key &key) { return _arr[ctr]->_value; } -template -const Val &HashMap::operator [](const Key &key) const { +template +const Val &HashMap::operator [](const Key &key) const { return queryVal(key); } -template -const Val &HashMap::queryVal(const Key &key) const { +template +const Val &HashMap::queryVal(const Key &key) const { uint ctr = lookup(key); assert(_arr[ctr] != NULL); return _arr[ctr]->_value; } -template -size_t HashMap::erase(const Key &key) { +template +size_t HashMap::erase(const Key &key) { // This is based on code in the Wikipedia article on Hash tables. uint i = lookup(key); if (_arr[i] == NULL)