Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 #ifndef __HashTable_H__ 00002 #define __HashTable_H__ 00003 00004 00005 #include <stddef.h> 00006 #include <assert.h> 00007 #include <stdio.h> 00008 00009 #include <map> 00010 #include <vector> 00011 #include <iostream> 00012 00013 00014 #define xDEBUG(flag,code) { if (flag) {code; fflush(stdout);} } 00015 #define DEB_HashTable 0 00016 00017 namespace stlCompatibility { 00018 00019 using namespace std; 00020 00021 // Hash functions for standard types (taken from ESTL) 00022 template <class _Key> struct Hash { }; 00023 00024 inline size_t hashString(const char* __s) 00025 { 00026 unsigned long __h = 0; 00027 for ( ; *__s; ++__s) 00028 __h = 5*__h + *__s; 00029 00030 return size_t(__h); 00031 } 00032 template<> struct Hash<char*> 00033 { 00034 size_t operator()(const char* __s) const { return hashString(__s); } 00035 }; 00036 template<> struct Hash<const char*> 00037 { 00038 size_t operator()(const char* __s) const { return hashString(__s); } 00039 }; 00040 template<> struct Hash<char> { 00041 size_t operator()(char __x) const { return __x; } 00042 }; 00043 template<> struct Hash<unsigned char> { 00044 size_t operator()(unsigned char __x) const { return __x; } 00045 }; 00046 template<> struct Hash<signed char> { 00047 size_t operator()(unsigned char __x) const { return __x; } 00048 }; 00049 template<> struct Hash<short> { 00050 size_t operator()(short __x) const { return __x; } 00051 }; 00052 template<> struct Hash<unsigned short> { 00053 size_t operator()(unsigned short __x) const { return __x; } 00054 }; 00055 template<> struct Hash<int> { 00056 size_t operator()(int __x) const { return __x; } 00057 }; 00058 template<> struct Hash<unsigned int> { 00059 size_t operator()(unsigned int __x) const { return __x; } 00060 }; 00061 template<> struct Hash<long> { 00062 size_t operator()(long __x) const { return __x; } 00063 }; 00064 template<> struct Hash<unsigned long> { 00065 size_t operator()(unsigned long __x) const { return __x; } 00066 }; 00067 //-------------------------------------------------------------------- 00068 00069 00070 template <class Key, class Value, 00071 class KeyHash = Hash<Key>, 00072 class KeyEq = equal_to<Key> > 00073 class HashTable { 00074 public: 00075 typedef Key KeyType; 00076 typedef Value ValueType; 00077 typedef KeyHash hasher; 00078 typedef KeyEq key_equal; 00079 00080 typedef pair<Key, Value> value_type; 00081 typedef pair<Key, Value> KeyValuePair; 00082 typedef pair<const Value, bool> ValueBoolPair; 00083 00084 private: 00085 typedef vector<KeyValuePair> KeyValuePairVector; 00086 typedef typename KeyValuePairVector::iterator KeyValuePairVectorIterator; 00087 typedef map<size_t, KeyValuePairVector, less<size_t> > Ht; 00088 typedef typename Ht::iterator HtIterator; 00089 typedef typename Ht::const_iterator HtConstIterator; 00090 00091 Ht ht; // size_t->KeyValuePairVector 00092 size_t _size; 00093 KeyHash keyHash; 00094 KeyEq keyEq; 00095 00096 public: 00097 KeyHash & hashClass() { return keyHash; } 00098 KeyEq & eqClass() { return keyEq; } 00099 00100 HashTable() { 00101 _size = 0; 00102 } 00103 00104 virtual ~HashTable() { 00105 clear(); 00106 } 00107 00108 public: 00109 void clear() { 00110 if (size() == 0) return; 00111 HtIterator htIterator; 00112 for ( htIterator = ht.begin(); 00113 htIterator != ht.end(); 00114 htIterator ++ ) { 00115 htIterator->second.clear(); 00116 } 00117 ht.clear(); 00118 _size = 0; 00119 } 00120 00121 size_t size() const { 00122 return _size; 00123 } 00124 00125 bool empty() const { 00126 return (_size == 0); 00127 } 00128 00129 size_t count(const Key& k) const { 00130 size_t h = keyHash(k); 00131 HtConstIterator htIterator = ht.find(h); 00132 if (htIterator == ht.end()) return 0; 00133 return htIterator->second.size(); 00134 } // count 00135 00136 ValueBoolPair find(const Key& k) const { 00137 size_t h = keyHash(k); 00138 HtConstIterator htIterator = ht.find(h); 00139 if (htIterator == ht.end()) return ValueBoolPair((const Value)NULL, false); 00140 00141 const KeyValuePairVector& kvpv = htIterator->second; 00142 typename KeyValuePairVector::const_iterator kvpvIterator; 00143 for ( kvpvIterator = kvpv.begin(); 00144 kvpvIterator != kvpv.end(); 00145 kvpvIterator ++ ) { 00146 const Key& kk = kvpvIterator->first; 00147 if (keyEq(k, kk) == true) return ValueBoolPair(kvpvIterator->second, true); 00148 } 00149 return ValueBoolPair((const Value)NULL, false); 00150 } // find 00151 00152 ValueBoolPair insert(const KeyValuePair& p) { 00153 size_t h = keyHash(p.first); 00154 HtIterator htIterator = ht.find(h); 00155 if (htIterator != ht.end()) { 00156 KeyValuePairVector& kvpv = htIterator->second; 00157 xDEBUG(DEB_HashTable, 00158 printf("insert: h=%u, ht.size()=%u, ht[h].size()=%u\n", h, ht.size(), kvpv.size()); 00159 ); 00160 KeyValuePairVectorIterator kvpvIterator; 00161 for ( kvpvIterator = kvpv.begin(); 00162 kvpvIterator != kvpv.end(); 00163 kvpvIterator ++ ) { 00164 Key& kk = kvpvIterator->first; 00165 if (keyEq(p.first, kk) == true) { 00166 return ValueBoolPair(kvpvIterator->second, false); 00167 } 00168 } 00169 kvpv.push_back(p); 00170 } else { 00171 xDEBUG(DEB_HashTable, 00172 printf("insert: h=%u, ht.size()=%u, ht[h].size()=%u\n", h, ht.size(), 0)); 00173 KeyValuePairVector kvpv; 00174 kvpv.push_back(p); 00175 pair<HtIterator, bool> tmp1 = ht.insert(typename Ht::value_type(h, kvpv)); 00176 assert(tmp1.second == true); 00177 } 00178 _size ++; 00179 return ValueBoolPair(p.second, true); 00180 } // insert 00181 00182 ValueBoolPair erase(const Key& k) { 00183 size_t h = keyHash(k); 00184 xDEBUG(DEB_HashTable, printf("erase: h=%u\n", h)); 00185 00186 HtIterator htIterator = ht.find(h); 00187 if (htIterator == ht.end()) return ValueBoolPair((const Value)NULL, false); 00188 00189 KeyValuePairVector& kvpv = htIterator->second; 00190 KeyValuePairVectorIterator kvpvIterator; 00191 for ( kvpvIterator = kvpv.begin(); 00192 kvpvIterator != kvpv.end(); 00193 kvpvIterator ++ ) { 00194 Key& kk = kvpvIterator->first; 00195 if (keyEq(k, kk) == true) { 00196 Value v = kvpvIterator->second; 00197 kvpv.erase(kvpvIterator); 00198 _size --; 00199 if (kvpv.empty()) ht.erase(htIterator); 00200 return ValueBoolPair(v, true); 00201 } 00202 } 00203 00204 assert(false); 00205 return ValueBoolPair((const Value)NULL, false); // should never reach! 00206 } // erase 00207 00208 ValueBoolPair modify(const KeyValuePair& p) { 00209 assert(false); 00210 return ValueKeyPair((const Value)NULL, false); 00211 } // modify 00212 00213 // The action must not change the membership of the data structure 00214 // Value v can be changed 00215 class ForAllAction { 00216 public: 00217 virtual void handle(const Key k, Value &v) = 0; 00218 }; 00219 00220 // oreder is NOT defined 00221 void forAll(ForAllAction & action) { 00222 HtIterator htIterator; 00223 KeyValuePairVectorIterator kvpvIterator; 00224 00225 for ( htIterator = ht.begin(); 00226 htIterator != ht.end(); 00227 htIterator ++ ) { 00228 KeyValuePairVector& kvpv = htIterator->second; 00229 for ( kvpvIterator = kvpv.begin(); 00230 kvpvIterator != kvpv.end(); 00231 kvpvIterator ++ ) { 00232 const Key& k = kvpvIterator->first; 00233 Value& v = kvpvIterator->second; 00234 00235 action.handle(k, v); 00236 } 00237 } 00238 } //forAll 00239 }; 00240 00241 } // namespace 00242 00243 #endif 00244 00245