Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
HashTable.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines