Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages

HashMap.h (Maintainer: Oliver Kohlbacher)

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // --------------------------------------------------------------------------
00005 //                   OpenMS Mass Spectrometry Framework
00006 // --------------------------------------------------------------------------
00007 //  Copyright (C) 2003-2008 -- Oliver Kohlbacher, Knut Reinert
00008 //
00009 //  This library is free software; you can redistribute it and/or
00010 //  modify it under the terms of the GNU Lesser General Public
00011 //  License as published by the Free Software Foundation; either
00012 //  version 2.1 of the License, or (at your option) any later version.
00013 //
00014 //  This library is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 //  Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with this library; if not, write to the Free Software
00021 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // --------------------------------------------------------------------------
00024 // $Maintainer: Oliver Kohlbacher $
00025 // --------------------------------------------------------------------------
00026 
00027 #ifndef OPENMS_DATASTRUCTURES_HASHMAP_H
00028 #define OPENMS_DATASTRUCTURES_HASHMAP_H
00029 
00030 #include <OpenMS/CONCEPT/Exception.h>
00031 #include<OpenMS/CONCEPT/Types.h>
00032 #include<OpenMS/CONCEPT/HashFunction.h>
00033 
00034 #include <utility>
00035 #include <algorithm>
00036 #include <iterator>
00037 #include <vector>
00038 
00039 namespace OpenMS
00040 {
00048   template <class Key, class T>
00049   class HashMap
00050   {
00051     public:
00052 
00053     // Convenience typedefs
00055     typedef std::pair<Key, T> ValueType;
00057     typedef Key KeyType;
00059     typedef std::pair<Key, T>* PointerType;
00060 
00061 
00067     struct Node
00068     {
00069       Node*     next;
00070       ValueType value;
00071 
00072       Node(const ValueType& my_value, const Node* my_next)
00073         throw()
00074         : next(const_cast<Node*>(my_next)),
00075           value(const_cast<ValueType&>(my_value))
00076       {
00077       }
00078     };
00079 
00080     class ConstIterator;
00081 
00088     class Iterator
00089     {
00090 
00091       friend class HashMap;
00092       friend class ConstIterator;
00093 
00094       public:
00095       typedef ValueType value_type;
00096       typedef Int difference_type;
00097       typedef std::forward_iterator_tag iterator_category;
00098       typedef value_type& reference;
00099       typedef value_type* pointer;
00100 
00101       Iterator() throw() {}
00102 
00103       Iterator(const Iterator& it) throw()
00104         : position_(it.position_),
00105           bucket_(it.bucket_),
00106           bound_(it.bound_)
00107       {
00108       }
00109 
00110       ~Iterator() throw() {}
00111 
00112       Iterator& operator = (const Iterator& it) throw()
00113       {
00114         position_ = it.position_;
00115         bucket_ = it.bucket_;
00116         bound_ = it.bound_;
00117         return *this;
00118       }
00119 
00120       bool operator == (const Iterator& it) const throw()
00121       {
00122         return (position_ == it.position_);
00123       }
00124 
00125       bool operator != (const Iterator& it) const throw()
00126       {
00127         return (position_ != it.position_);
00128       }
00129 
00130       reference operator * () throw()
00131       {
00132         return **position_;
00133       }
00134 
00135       const reference operator * () const throw()
00136       {
00137         return *position_;
00138       }
00139 
00140       pointer operator -> () throw()
00141       {
00142         return &position_->value;
00143       }
00144 
00145       const pointer operator -> () const
00146       {
00147         return &position_->value;
00148       }
00149 
00150       Iterator& operator ++ ()
00151       {
00152         position_ = position_->next;
00153 
00154         if (position_ == 0)
00155         {
00156           for (++bucket_;  bucket_ < (UInt)bound_->bucket_.size();  ++bucket_)
00157           {
00158             position_ = bound_->bucket_[bucket_];
00159 
00160             if (position_ != 0)
00161             {
00162               return *this;
00163             }
00164           }
00165         }
00166 
00167         return *this;
00168       }
00169 
00170       Iterator operator ++ (int)
00171       {
00172         Iterator tmp(*this);
00173         ++(*this);//????
00174         return tmp;
00175       }
00176 
00177       static Iterator end(const HashMap& hm)
00178       {
00179         Iterator it;
00180         it.position_ = 0;
00181         it.bound_ = const_cast<HashMap*>(&hm);
00182         it.bucket_ = 0;
00183         return it;
00184       }
00185 
00186       static Iterator begin(const HashMap& hm)
00187       {
00188         Iterator it;
00189         it.bound_ = const_cast<HashMap*>(&hm);
00190         for (it.bucket_ = 0;  it.bucket_ < hm.bucket_.size();  ++it.bucket_)
00191         {
00192           it.position_ = hm.bucket_[it.bucket_];
00193 
00194           if (it.position_ != 0)
00195           {
00196             return it;
00197           }
00198         }
00199         return it;
00200       }
00201 
00202       protected:
00203       Node* position_;
00204       UInt bucket_;
00205       HashMap* bound_;
00206     };
00207 
00214     class ConstIterator
00215     {
00216       friend class HashMap;
00217 
00218       public:
00219       typedef ValueType value_type;
00220       typedef Int difference_type;
00221       typedef const ValueType& reference;
00222       typedef const ValueType* pointer;
00223       typedef std::forward_iterator_tag iterator_category;
00224 
00225       ConstIterator() throw()
00226         : position_(0),
00227           bucket_(0),
00228           bound_(0)
00229       {
00230       }
00231 
00232       ConstIterator(const ConstIterator& it) throw()
00233         : position_(it.position_),
00234           bucket_(it.bucket_),
00235           bound_(it.bound_)
00236       {
00237       }
00238 
00239       ConstIterator(const Iterator& it)
00240         : position_(it.position_),
00241           bucket_(it.bucket_),
00242           bound_(it.bound_)
00243       {
00244       }
00245 
00246       ~ConstIterator() throw() {}
00247 
00248       ConstIterator& operator = (const ConstIterator& it)
00249       {
00250         position_ = it.position_;
00251         bucket_ = it.bucket_;
00252         bound_ = it.bound_;
00253         return *this;
00254       }
00255 
00256       ConstIterator& operator = (const Iterator& it)
00257       {
00258         position_ = it.position_;
00259         bucket_ = it.bucket_;
00260         bound_ = it.bound_;
00261         return *this;
00262       }
00263 
00264       bool operator == (const Iterator& it) const
00265       {
00266         return position_ == it.position_;
00267       }
00268 
00269       bool operator != (const Iterator& it) const
00270       {
00271         return position_ != it.position_;
00272       }
00273 
00274       bool operator == (const ConstIterator& it) const
00275       {
00276         return position_ == it.position_;
00277       }
00278 
00279       bool operator != (const ConstIterator& it) const
00280       {
00281         return position_ != it.position_;
00282       }
00283 
00284       ConstIterator& operator ++ ()
00285       {
00286         position_ = position_->next;
00287 
00288         if (position_ == 0)
00289         {
00290           for (++bucket_;  bucket_ < (UInt)bound_->bucket_.size();  ++bucket_)
00291           {
00292             position_ = bound_->bucket_[bucket_];
00293 
00294             if (position_ != 0)
00295             {
00296               return *this;
00297             }
00298           }
00299         }
00300 
00301         return *this;
00302       }
00303 
00304       ConstIterator operator ++ (int)
00305       {
00306         ConstIterator tmp(*this);
00307         ++(*this);
00308         return tmp;
00309       }
00310 
00311       ConstIterator& operator -- ()
00312       {
00313         --position_;
00314         return *this;
00315       }
00316 
00317       ConstIterator operator -- (int)
00318       {
00319         ConstIterator tmp(*this);
00320         --(*this);
00321         return tmp;
00322       }
00323 
00324       reference operator * () const
00325       {
00326         return position_->value;
00327       }
00328 
00329       pointer operator -> () const
00330       {
00331         return &position_->value;
00332       }
00333 
00334       static ConstIterator end(const HashMap& hm)
00335       {
00336         ConstIterator it;
00337         it.position_ = 0;
00338         it.bucket_ = 0;
00339         it.bound_ = &hm;
00340         return it;
00341       }
00342 
00343       static ConstIterator begin(const HashMap& hm)
00344       {
00345         ConstIterator it;
00346         it.bound_ = &hm;
00347         for (it.bucket_ = 0;  it.bucket_ < hm.bucket_.size();  ++it.bucket_)
00348         {
00349           it.position_ = hm.bucket_[it.bucket_];
00350 
00351           if (it.position_ != 0)
00352           {
00353             return it;
00354           }
00355         }
00356         return it;
00357       }
00358 
00359       protected:
00360       Node* position_;
00361       UInt bucket_;
00362       const HashMap* bound_;
00363     };
00364 
00365 
00366     typedef std::reverse_iterator<Iterator> ReverseIterator;
00367     typedef std::reverse_iterator<ConstIterator> ConstReverseIterator;
00368 
00372 
00373     typedef ValueType value_type;
00374     typedef UInt size_type;
00375     typedef Int difference_type;
00377     typedef ValueType& reference;
00378     typedef const ValueType& const_reference;
00380     typedef ValueType& pointer;
00382     typedef Iterator iterator;
00383     typedef ConstIterator const_iterator;
00384     typedef ReverseIterator reverse_iterator;
00385     typedef ConstReverseIterator const_reverse_iterator;
00387 
00391     enum
00392     {
00394       INITIAL_CAPACITY          = 100,
00395 
00397       INITIAL_NUMBER_OF_BUCKETS = 50
00398     };
00400 
00404 
00410     class IllegalKey
00411       : public Exception::Base
00412     {
00413       public:
00414       IllegalKey(const char* file, int line, const char* function)
00415         : Exception::Base(file, line, function) {}
00416     };
00417 
00419 
00423 
00429     HashMap(UInt initial_capacity = INITIAL_CAPACITY, UInt number_of_buckets = INITIAL_NUMBER_OF_BUCKETS)
00430       throw();
00431 
00434     HashMap(const HashMap& hash_map) throw();
00435 
00438     inline
00439     virtual ~HashMap() throw()
00440     {
00441       destroy();
00442       deleteBuckets_();
00443     }
00444 
00449     virtual void clear() throw();
00450 
00456     void destroy() throw();
00457 
00459 
00462 
00466     void set(const HashMap& hash_map) throw();
00467 
00472     const HashMap& operator = (const HashMap& hash_map) throw();
00473 
00476     void get(HashMap& hash_map) const throw();
00477 
00480     void swap(HashMap& hash_map) throw();
00481 
00483 
00486 
00489     UInt getBucketSize() const throw();
00490 
00493     UInt getCapacity() const throw();
00494 
00497     UInt getSize() const throw();
00498 
00501     UInt size() const throw();
00502 
00505     Iterator find(const Key& key) throw()
00506     {
00507       Iterator it = end();
00508       UInt bucket = hash_(key);
00509       Node* node_ptr = bucket_[hash_(key)];
00510 
00511       for (; node_ptr != 0; node_ptr = node_ptr->next)
00512       {
00513         if (node_ptr->value.first == key)
00514         {
00515           it.position_ = node_ptr;
00516           it.bucket_ = bucket;
00517           break;
00518         }
00519       }
00520 
00521       return it;
00522     }
00523 
00526     ConstIterator find(const Key& key) const throw()
00527     {
00528       ConstIterator it = end();
00529       UInt bucket = hash_(key);
00530       Node* node_ptr = bucket_[hash_(key)];
00531 
00532       for (; node_ptr != 0; node_ptr = node_ptr->next)
00533       {
00534         if (node_ptr->value.first == key)
00535         {
00536           it.position_ = node_ptr;
00537           it.bucket_ = bucket;
00538           break;
00539         }
00540       }
00541 
00542       return it;
00543     }
00544 
00549     T& operator [] (const Key& key) throw();
00550 
00555     const T& operator [] (const Key& key) const
00556       throw(typename HashMap<Key, T>::IllegalKey);
00557 
00560     std::pair<Iterator, bool> insert(const ValueType& entry) throw();
00561 
00565     Iterator insert(Iterator pos, const ValueType& entry) throw();
00566 
00570     UInt erase(const Key& key) throw();
00571 
00575     void erase(Iterator pos) throw();
00576 
00580     void erase(Iterator first, Iterator last) throw();
00581 
00583 
00584 
00588 
00591     bool has(const Key& key) const throw();
00592 
00595     bool isEmpty() const throw();
00596 
00599     bool operator == (const HashMap& hash_map) const throw();
00600 
00603     bool operator != (const HashMap& hash_map) const throw();
00604 
00606 
00607     inline Iterator begin() throw()
00608     {
00609       return Iterator::begin(*this);
00610     }
00611 
00612     inline Iterator end() throw()
00613     {
00614       return Iterator::end(*this);
00615     }
00616 
00617     inline ConstIterator begin() const throw()
00618     {
00619       return ConstIterator::begin(*this);
00620     }
00621 
00622     inline ConstIterator end() const throw()
00623     {
00624       return ConstIterator::end(*this);
00625     }
00626 
00627 
00628     protected:
00629 
00630     virtual Node* newNode_(const ValueType& value, Node* next) const throw();
00631 
00632     virtual void deleteNode_(Node* node) const throw();
00633 
00634     virtual UInt getHashKey_(const Key& key) const throw();
00635 
00636     virtual bool needRehashing_() const throw();
00637 
00638     virtual void recalculateCapacity_() throw();
00639 
00640     PointerType find_(const Key& key, UInt& index) throw();
00641 
00642     PointerType find_(const Key& key, UInt& index) const throw();
00643 
00644     void deleteBuckets_() throw();
00645 
00646     UInt hash_(const Key& key) const throw();
00647 
00648     void rehash_() throw();
00649 
00653 
00656     UInt size_;
00659     UInt capacity_;
00660 
00663     std::vector<Node*> bucket_;
00664 
00666   };
00667 
00668   template <class Key, class T>
00669   inline
00670   HashMap<Key, T>::HashMap(UInt initial_capacity, UInt number_of_buckets)
00671     throw()
00672     : size_(0),
00673       capacity_(initial_capacity),
00674       bucket_(number_of_buckets)
00675   {
00676     for (UInt bucket = 0; bucket < (UInt)bucket_.size(); ++bucket)
00677     {
00678       bucket_[bucket] = 0;
00679     }
00680   }
00681 
00682   template <class Key, class T>
00683   inline
00684   HashMap<Key, T>::HashMap(const HashMap& hash_map)
00685     throw()
00686     : size_(hash_map.size_),
00687       capacity_(hash_map.capacity_),
00688       bucket_((UInt)hash_map.bucket_.size())
00689   {
00690     Node* node = 0;
00691 
00692     for (UInt bucket = 0; bucket < (UInt)bucket_.size(); ++bucket)
00693     {
00694       bucket_[bucket] = 0;
00695 
00696       for (node = hash_map.bucket_[bucket]; node != 0; node = node->next)
00697       {
00698         bucket_[bucket] = newNode_(node->value, bucket_[bucket]);
00699       }
00700     }
00701   }
00702 
00703   template <class Key, class T>
00704   void HashMap<Key, T>::clear()
00705     throw()
00706   {
00707     Node* node = 0;
00708     Node* next_node = 0;
00709 
00710     for (UInt bucket = 0; bucket < (UInt)bucket_.size(); ++bucket)
00711     {
00712       for (node = bucket_[bucket]; node != 0; node = next_node)
00713       {
00714         next_node = node->next;
00715         deleteNode_(node);
00716       }
00717 
00718       bucket_[bucket] = 0;
00719     }
00720 
00721     size_ = 0;
00722   }
00723 
00724   template <class Key, class T>
00725   inline
00726   void HashMap<Key, T>::destroy()
00727     throw()
00728   {
00729     clear();
00730   }
00731 
00732   template <class Key, class T>
00733   void HashMap<Key, T>::set(const HashMap& hash_map)
00734     throw()
00735   {
00736     if (&hash_map == this)
00737     {
00738       return;
00739     }
00740 
00741     destroy();
00742     deleteBuckets_();
00743 
00744     size_ = hash_map.size_;
00745     capacity_ = hash_map.capacity_;
00746     bucket_.resize(hash_map.bucket_.size());
00747 
00748     Node* node = 0;
00749 
00750     for (UInt bucket = 0; bucket < (UInt)bucket_.size(); ++bucket)
00751     {
00752       bucket_[bucket] = 0;
00753 
00754       for (node = hash_map.bucket_[bucket]; node != 0; node = node->next)
00755       {
00756         bucket_[bucket] = newNode_(node->value, bucket_[bucket]);
00757       }
00758     }
00759   }
00760 
00761   template <class Key, class T>
00762   inline
00763   const HashMap<Key, T>& HashMap<Key, T>::operator = (const HashMap& hash_map)
00764     throw()
00765   {
00766     set(hash_map);
00767     return *this;
00768   }
00769 
00770   template <class Key, class T>
00771   inline
00772   void HashMap<Key, T>::get(HashMap& hash_map) const
00773     throw()
00774   {
00775     hash_map.set(*this);
00776   }
00777 
00778   template <class Key, class T>
00779   inline
00780   void HashMap<Key, T>::swap(HashMap& hash_map)
00781     throw()
00782   {
00783     std::swap(size_, hash_map.size_);
00784     std::swap(capacity_, hash_map.capacity_);
00785     std::swap(bucket_, hash_map.bucket_);
00786   }
00787 
00788   template <class Key, class T>
00789   inline
00790   UInt HashMap<Key, T>::getBucketSize() const
00791     throw()
00792   {
00793     return (UInt)bucket_.size();
00794   }
00795 
00796   template <class Key, class T>
00797   inline
00798   UInt HashMap<Key, T>::getCapacity() const
00799     throw()
00800   {
00801     return capacity_;
00802   }
00803 
00804   template <class Key, class T>
00805   inline
00806   UInt HashMap<Key, T>::getSize() const
00807     throw()
00808   {
00809     return size_;
00810   }
00811 
00812   template <class Key, class T>
00813   inline
00814   UInt HashMap<Key, T>::size() const
00815     throw()
00816   {
00817     return size_;
00818   }
00819 
00820   template <class Key, class T>
00821   inline
00822   T& HashMap<Key, T>::operator [] (const Key& key)
00823     throw()
00824   {
00825     Iterator it = find(key);
00826     if (it == end())
00827     {
00828       it = insert(ValueType(key, T())).first;
00829     }
00830 
00831     return it->second;
00832   }
00833 
00834   template <class Key, class T>
00835   inline
00836   const T& HashMap<Key, T>::operator [] (const Key& key) const
00837     throw(typename HashMap<Key, T>::IllegalKey)
00838   {
00839     ConstIterator it = find(key);
00840     if (it == end())
00841     {
00842       throw IllegalKey(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00843     }
00844     else
00845     {
00846       return it->second;
00847     }
00848   }
00849 
00850   template <class Key, class T>
00851   ::std::pair<typename HashMap<Key, T>::Iterator, bool> HashMap<Key, T>::insert
00852     (const ValueType& item) throw()
00853   {
00854     Iterator it = find(item.first);
00855     if (it == end())
00856     {
00857       if (needRehashing_() == true)
00858       {
00859         rehash_();
00860       }
00861 
00862       UInt bucket = hash_(item.first);
00863 
00864       Node* node_ptr = bucket_[bucket];
00865       bucket_[bucket] = newNode_(item, node_ptr);
00866 
00867       ++size_;
00868       it.position_  = bucket_[bucket];
00869       it.bucket_    = bucket;
00870 
00871       return std::pair<Iterator, bool>(it, true);
00872     }
00873     else
00874     {
00875       // replace the existing value
00876       it->second = item.second;
00877 
00878       return ::std::pair<Iterator, bool>(it, false);
00879     }
00880   }
00881 
00882   template <class Key, class T>
00883   inline
00884   typename HashMap<Key, T>::Iterator HashMap<Key, T>::insert
00885     (typename HashMap<Key, T>::Iterator /* pos */, const ValueType& entry)  throw()
00886   {
00887     return insert(entry).first;
00888   }
00889 
00890   template <class Key, class T>
00891   UInt HashMap<Key, T>::erase(const Key& key)
00892     throw()
00893   {
00894     Node* previous = 0;
00895     UInt bucket = hash_(key);
00896     Node* node_ptr = bucket_[bucket];
00897 
00898     while (node_ptr != 0 && node_ptr->value.first != key)
00899     {
00900       previous = node_ptr;
00901       node_ptr = node_ptr->next;
00902     }
00903 
00904     if (node_ptr == 0)
00905     {
00906       return false;
00907     }
00908 
00909     if (node_ptr == bucket_[bucket])
00910     {
00911       bucket_[bucket] = node_ptr->next;
00912     }
00913     else
00914     {
00915       previous->next = node_ptr->next;
00916     }
00917 
00918     deleteNode_(node_ptr);
00919     --size_;
00920 
00921     return true;
00922   }
00923 
00924   template <class Key, class T>
00925   void HashMap<Key, T>::erase(Iterator pos)
00926     throw()
00927   {
00928     if ((pos == end()) || (size_ == 0))
00929     {
00930       return;
00931     }
00932 
00933     if (pos.position_ == bucket_[pos.bucket_])
00934     {
00935       bucket_[pos.bucket_] = pos.position_->next;
00936     }
00937     else
00938     {
00939       // walk over all nodes in this bucket and identify the predecessor
00940       // of the node refered to by the iterator pos
00941       Node* prev = bucket_[pos.bucket_];
00942       for (; (prev != 0) && (prev->next != pos.position_); prev = prev->next);
00943       if (prev != 0)
00944       {
00945         // remove the node and reconnect the list
00946         prev->next = pos.position_->next;
00947       }
00948       else
00949       {
00950         throw Exception::InvalidIterator(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00951       }
00952     }
00953 
00954     // delete the node and decrement the set size
00955     deleteNode_(pos.position_);
00956     --size_;
00957   }
00958 
00959   template <class Key, class T>
00960   void HashMap<Key, T>::erase(Iterator f, Iterator l)
00961     throw()
00962   {
00963     if (f == end())
00964     {
00965       return;
00966     }
00967 
00968     UInt last_bucket = l.bucket_;
00969     if (l == end())
00970     {
00971       last_bucket = (UInt)bucket_.size() - 1;
00972     }
00973 
00974     if (f.bucket_ > last_bucket)
00975     {
00976       // empty range - l < f
00977       return;
00978     }
00979 
00980     // count the deleted entries to correct the set size
00981     UInt no_deletions = 0;
00982 
00983     UInt bucket = f.bucket_;
00984     for (; bucket <= last_bucket; bucket++)
00985     {
00986       if (bucket_[bucket] == 0)
00987       {
00988         // skip all empty buckets
00989         continue;
00990       }
00991 
00992       if ((bucket == f.bucket_) && (bucket_[bucket] != f.position_))
00993       {
00994         // find the predecessor of f
00995         Node* n = bucket_[bucket];
00996         Node* next;
00997         for (; (n->next != f.position_) && (n->next != 0); n = n->next);
00998 
00999         if (bucket == last_bucket)
01000         {
01001           // delete everything from f to l in this bucket
01002 
01003           next = n->next;
01004           n->next = l.position_;
01005           for (n = next; (n != 0) && (n != l.position_); n = next)
01006           {
01007             next = n->next;
01008             deleteNode_(n);
01009             no_deletions++;
01010           }
01011         }
01012         else
01013         {
01014           // delete everything from f to the end in this bucket
01015 
01016           if (n != 0)
01017           {
01018             // mark the end of the list
01019             next = n->next;
01020             n->next = 0;
01021 
01022             // delete all remaining nodes
01023             for (n = next; n != 0; n = next)
01024             {
01025               next = n->next;
01026               deleteNode_(n);
01027               no_deletions++;
01028             }
01029           }
01030         }
01031       }
01032       // if the current bucket lies between the first and the last bucket...
01033       else if (bucket < last_bucket)
01034       {
01035         // ...delete the whole bucket
01036         Node* next;
01037         for (Node* n = bucket_[bucket]; n != 0; n = next)
01038         {
01039           next = n->next;
01040           deleteNode_(n);
01041           no_deletions++;
01042         }
01043         bucket_[bucket] = 0;
01044       }
01045       else if (bucket == last_bucket)
01046       {
01047         // we delete everything in this bucket up to the iterator l
01048 
01049         // find the predecessor of l
01050         Node* n = bucket_[bucket];
01051         Node* next;
01052         for (; (n != 0) && (n != l.position_); n = next)
01053         {
01054           next = n->next;
01055           deleteNode_(n);
01056           no_deletions++;
01057         }
01058 
01059         bucket_[bucket] = l.position_;
01060       }
01061     }
01062 
01063     // correct the set size
01064     size_ -= no_deletions;
01065   }
01066 
01067   template <class Key, class T>
01068   inline
01069   bool HashMap<Key, T>::has(const Key& key) const
01070     throw()
01071   {
01072     return (find(key) != end());
01073   }
01074 
01075   template <class Key, class T>
01076   inline
01077   bool HashMap<Key, T>::isEmpty() const
01078     throw()
01079   {
01080     return (size_ == 0);
01081   }
01082 
01083   template <class Key, class T>
01084   bool HashMap<Key, T>::operator == (const HashMap& hash_map) const
01085     throw()
01086   {
01087     if (size_ != hash_map.size_)
01088     {
01089       return false;
01090     }
01091 
01092     for (ConstIterator it(begin()); it != end(); ++it)
01093     {
01094       ConstIterator hash_map_it(hash_map.find(it->first));
01095       if ((hash_map_it == hash_map.end()) || (hash_map_it->second != it->second))
01096       {
01097         return false;
01098       }
01099     }
01100 
01101     return true;
01102   }
01103 
01104   template <class Key, class T>
01105   inline
01106   bool HashMap<Key, T>::operator != (const HashMap& hash_map) const
01107     throw()
01108   {
01109     return !(*this == hash_map);
01110   }
01111 
01112   template <class Key, class T>
01113   inline UInt HashMap<Key, T>::getHashKey_(const Key& key) const
01114     throw()
01115   {
01116     return Hash(key);
01117   }
01118 
01119   template <class Key, class T>
01120   inline void HashMap<Key, T>::recalculateCapacity_()
01121     throw()
01122   {
01123     capacity_ = (UInt)getNextPrime((UInt)bucket_.size() * 2);
01124   }
01125 
01126 
01127   template <class Key, class T>
01128   void HashMap<Key, T>::deleteBuckets_()
01129     throw()
01130   {
01131     Node* node = 0;
01132     Node* next_node = 0;
01133     for (UInt i = 0; i < (UInt)bucket_.size(); i++)
01134     {
01135       node = bucket_[i];
01136       while (node != 0)
01137       {
01138         next_node = node->next;
01139         deleteNode_(node);
01140         node = next_node;
01141       }
01142       bucket_[i] = 0;
01143     }
01144   }
01145 
01146   template <class Key, class T>
01147   inline typename HashMap<Key, T>::Node* HashMap<Key, T>::newNode_
01148     (const ValueType& value, typename HashMap<Key, T>::Node* next) const
01149     throw()
01150   {
01151     return new Node(value, next);
01152   }
01153 
01154   template <class Key, class T>
01155   inline void HashMap<Key, T>::deleteNode_(typename HashMap<Key, T>::Node* node) const
01156     throw()
01157   {
01158     delete node;
01159   }
01160 
01161   template <class Key, class T>
01162   inline bool HashMap<Key, T>::needRehashing_() const
01163     throw()
01164   {
01165     return (size_ >= capacity_);
01166   }
01167 
01168 
01169   template <class Key, class T>
01170   inline UInt HashMap<Key, T>::hash_(const Key& key) const
01171     throw()
01172   {
01173     return (UInt)(getHashKey_(key) % bucket_.size());
01174   }
01175 
01176   template <class Key, class T>
01177   void HashMap<Key, T>::rehash_()
01178     throw()
01179   {
01180     // calculate the new number of buckets (in capacity_)
01181     recalculateCapacity_();
01182 
01183     // save the old contents
01184     std::vector<Node*> old_buckets(bucket_);
01185 
01186     // resize the bucket vector and initialize it with zero
01187     bucket_.clear();
01188     bucket_.resize(capacity_);
01189     UInt i;
01190     for (i = 0; i < capacity_; i++)
01191     {
01192       bucket_[i] = 0;
01193     }
01194 
01195     // rehash the old contents into the new buckets
01196     Node* node;
01197     Node* next_node;
01198     for (UInt i = 0; i < (UInt)old_buckets.size(); ++i)
01199     {
01200       for (node = old_buckets[i]; node != 0; node = next_node)
01201       {
01202         next_node = node->next;
01203         UInt new_bucket = (UInt)hash_(node->value.first);
01204         node->next = bucket_[new_bucket];
01205         bucket_[new_bucket] = node;
01206       }
01207     }
01208   }
01209 } // namespace OPENMS
01210 
01211 #endif // OPENMS_DATASTRUCTURES_HASHMAP_H

Generated Tue Apr 1 15:36:35 2008 -- using doxygen 1.5.4 OpenMS / TOPP 1.1