// @HEADER // *********************************************************************** // // Teuchos: Common Tools Package // Copyright (2004) Sandia Corporation // // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive // license for use of this work by or on behalf of the U.S. Government. // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA // Questions? Contact Michael A. Heroux (maherou@sandia.gov) // // *********************************************************************** // @HEADER #ifndef TEUCHOS_HASHSET_H #define TEUCHOS_HASHSET_H /*! \file Teuchos_HashSet.hpp \brief Templated hashtable-based set */ #include "Teuchos_ConfigDefs.hpp" #include "Teuchos_Array.hpp" #include "Teuchos_HashUtils.hpp" namespace Teuchos { using std::string; /** \ingroup Containers * \brief Templated hashtable-based set. HashSet is a hashtable-based set, similar to the STL set class * or the Java HashSet class. */ template class HashSet { public: //! Create an empty HashSet inline HashSet(int capacity=19); //! Check for the presence of a key inline bool containsKey(const Key& key) const ; //! Put a new object into the table. inline void put(const Key& key); //! Remove from the table the element given by key. inline void remove(const Key& key); //! Get the number of elements in the table inline int size() const {return count_;} //! Get list of keys in Array form inline Array arrayify() const ; //! Get list of keys in Array form inline void arrayify(Array& keys) const ; //! Write to a std::string inline std::string toString() const ; private: /** rebuild the hashtable when the size has changed */ inline void rehash(); /** get the next prime number near a given capacity */ inline int nextPrime(int newCap) const ; Array > data_; int count_; int capacity_; mutable Key mostRecentKey_; }; /** \relates HashSet \brief Write HashSet to a stream */ template std::ostream& operator<<(std::ostream& os, const HashSet& h); template inline std::string toString(const HashSet& h) {return h.toString();} template inline HashSet::HashSet(int capacity) : data_(), count_(0), capacity_(HashUtils::nextPrime(capacity)) { data_.resize(capacity_); } template inline bool HashSet::containsKey(const Key& key) const { const Array& candidates = data_[hashCode(key) % capacity_]; for (int i=0; i inline void HashSet::put(const Key& key) { int index = hashCode(key) % capacity_; Array& local = data_[index]; // check for duplicate key for (int i=0; i capacity_) { capacity_ = HashUtils::nextPrime(capacity_+1); rehash(); // recaluate index index = hashCode(key) % capacity_; } data_[index].append(key); } template inline void HashSet::rehash() { Array > tmp(capacity_); for (int i=0; i inline Array HashSet::arrayify() const { Array rtn; rtn.reserve(size()); for (int i=0; i inline void HashSet::arrayify(Array& rtn) const { rtn.resize(0); for (int i=0; i inline std::string HashSet::toString() const { std::string rtn = "HashSet["; bool first = true; for (int i=0; i inline void HashSet::remove(const Key& key) { TEST_FOR_EXCEPTION(!containsKey(key), std::runtime_error, "HashSet::remove: key " << Teuchos::toString(key) << " not found in HashSet" << toString()); count_--; int h = hashCode(key) % capacity_; Array& candidates = data_[h]; for (int i=0; i inline std::ostream& operator<<(std::ostream& os, const HashSet& h) { return os << h.toString(); } } #endif // TEUCHOS_HASHSET_H