3 // ---------------------------------------------------------------------------
 
    5 #ifndef HEP_HASH_MAP_SRC
 
    6 #define HEP_HASH_MAP_SRC
 
   10 #include "CLHEP/Evaluator/string.icc"
 
   13  * Simplified hash_map class.
 
   14  * It provides only basic functions of the standard <hash_map> and
 
   15  * is intended to be used as a replacement of the standard class where
 
   16  * full functionality of <hash_map> is not required, but it is essential
 
   17  * to have highly portable and effective code.
 
   19  * This file should be used exclusively inside *.cc files.
 
   20  * Usage inside header files can result to a clash with standard <hash_map>.
 
   22  * @author Evgeni Chernyaev  <Evgueni.Tcherniaev@cern.ch>
 
   24 template<class K, class T>
 
   27   struct Entry {            // Hash_map entry   
 
   28     std::pair<const K,T> data;
 
   30     Entry(K k, T v, Entry* n) : data(k,v), next(n) {}
 
   33   class hash_map_iterator { // Hash_map iterator
 
   36     hash_map_iterator() : entry(0) {}
 
   37     hash_map_iterator(Entry & e) : entry(&e) {} 
 
   38     std::pair<const K,T> & operator * () const { return entry->data; }
 
   39     std::pair<const K,T> * operator ->() const { return &(operator*()); }
 
   40     bool operator==(hash_map_iterator i) const {
 
   41       return (entry == i.entry);
 
   43     bool operator!=(hash_map_iterator i) const {
 
   44       return (entry != i.entry);
 
   49   typedef unsigned int            size_type;
 
   50   typedef std::pair<const K,T> value_type;
 
   51   typedef hash_map_iterator       iterator;
 
   52   typedef hash_map_iterator       const_iterator;
 
   55   Entry**   table;          // Hash table: pointers to entries
 
   56   size_type cur_size;       // Number of entries
 
   57   size_type max_size;       // Bucket_count - current size of the table
 
   58   float     max_load;       // Keep (n) <= (max_size * max_load)
 
   59   float     grow;           // When necessary, resize(max_size * grow)
 
   60   const T   default_value;  // Default value used by []
 
   62   size_type hash(const char * key) const {
 
   64     while(*key) { res = res*31 + *key++; }
 
   68   size_type hash(const string & key) const {
 
   69     return hash(key.c_str());
 
   72   bool eq(const char * a, const char * b) const {
 
   73     return (strcmp(a, b) == 0);
 
   76   bool eq(const string & a, const string & b) const {
 
   83   hash_map(const T & dv = T(), size_type n = 107)
 
   84     : table(0), cur_size(0), max_size(0), default_value(dv)
 
   92     for(size_type i=0; i<max_size; i++) {
 
   94       while(n) { Entry* p = n; n = p->next; delete p; }
 
   99   // Sets load and grow parameters.
 
  100   void set_load(float m = 0.7, float g = 1.7) { max_load = m; grow = g; } 
 
  102   // Returns number of elements.
 
  103   size_type size() const { return cur_size; }
 
  105   // Returns size of the hash table.
 
  106   size_type bucket_count() const { return max_size; }
 
  108   // Resizes the hash table.
 
  109   void resize(size_type s) {
 
  110     if (s <= max_size) return;
 
  112     table = new Entry* [s];
 
  113     for (size_type k=0; k<s; k++) table[k] = 0;
 
  114     for (size_type i=0; i<max_size; i++) {
 
  119    size_type ii = hash(p->data.first) % s;
 
  129   T & operator[](const K & key) {
 
  130     size_type i = hash(key) % max_size;
 
  131     for (Entry* p=table[hash(key) % max_size]; p; p=p->next) {
 
  132       if (eq(key,p->data.first)) return p->data.second;
 
  134     if (cur_size++ >= max_size*max_load) {
 
  135       resize(size_type(max_size*grow));
 
  136       i = hash(key) % max_size;
 
  138     table[i] = new Entry(key, default_value, table[i]);
 
  139     return table[i]->data.second;
 
  142   // Finds element with given key.  
 
  143   iterator find(const K & key) const {
 
  144     size_type i = hash(key) % max_size;
 
  145     for (Entry* p=table[i]; p; p=p->next) {
 
  146       if (eq(key,p->data.first)) return iterator(*p);
 
  151   // Erases element with given key.
 
  152   size_type erase(const K & key) {
 
  153     size_type i = hash(key) % max_size;
 
  155     if (p == 0) return 0;
 
  156     if (eq(key,p->data.first)) {
 
  157       table[i] = p->next; delete p; cur_size--; return 1;
 
  159     Entry** pp = &table[i];
 
  160     for (p=p->next; p; p=p->next) {
 
  161       if (eq(key,p->data.first)) {
 
  162    *pp = p->next; delete p; cur_size--; return 1;
 
  170   // Clears the hash table.
 
  172     for(size_type i=0; i<max_size; i++) {
 
  173       for (Entry* p=table[i]; p;) {
 
  174    Entry* pp = p; p = p->next; delete pp;
 
  181   // Returns end iterator.
 
  182   iterator end() const { return iterator(); }
 
  186 #endif /* HEP_HASH_MAP_SRC */