Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_HashSet.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TEUCHOS_HASHSET_H
11 #define TEUCHOS_HASHSET_H
12 
17 #include "Teuchos_ConfigDefs.hpp"
18 #include "Teuchos_Array.hpp"
19 #include "Teuchos_HashUtils.hpp"
20 
21 namespace Teuchos
22 {
23  using std::string;
24 
25 
32  template<class Key> class HashSet
33  {
34  public:
35 
37  inline HashSet(int capacity=19);
38 
40  inline bool containsKey(const Key& key) const ;
41 
43  inline void put(const Key& key);
44 
46  inline void remove(const Key& key);
47 
49  inline int size() const {return count_;}
50 
52  inline Array<Key> arrayify() const ;
53 
55  inline void arrayify(Array<Key>& keys) const ;
56 
58  inline std::string toString() const ;
59 
60  private:
62  inline void rehash();
64  inline int nextPrime(int newCap) const ;
65 
67  int count_;
68  int capacity_;
69  mutable Key mostRecentKey_;
70  };
71 
72 
76  template<class Key>
77  std::ostream& operator<<(std::ostream& os, const HashSet<Key>& h);
78 
79  template<class Key> inline
80  std::string toString(const HashSet<Key>& h) {return h.toString();}
81 
82 
83  template<class Key> inline
84  HashSet<Key>::HashSet(int capacity)
85  : data_(), count_(0), capacity_(HashUtils::nextPrime(capacity))
86  {
87  data_.resize(capacity_);
88  }
89 
90  template<class Key> inline
91  bool HashSet<Key>::containsKey(const Key& key) const
92  {
93  const Array<Key>& candidates
94  = data_[hashCode(key) % capacity_];
95 
96  for (int i=0; i<candidates.length(); i++)
97  {
98  const Key& c = candidates[i];
99  if (c == key)
100  {
101  return true;
102  }
103  }
104  return false;
105  }
106 
107  template<class Key> inline
108  void HashSet<Key>::put(const Key& key)
109  {
110  int index = hashCode(key) % capacity_;
111 
112  Array<Key>& local = data_[index];
113 
114  // check for duplicate key
115  for (int i=0; i<local.length(); i++)
116  {
117  if (local[i] == key)
118  {
119  return;
120  }
121  }
122 
123  // no duplicate key, so increment element count by one.
124  count_++;
125 
126  // check for need to resize.
127  if (count_ > capacity_)
128  {
129  capacity_ = HashUtils::nextPrime(capacity_+1);
130  rehash();
131  // recaluate index
132  index = hashCode(key) % capacity_;
133  }
134 
135  data_[index].append(key);
136  }
137 
138 
139 
140  template<class Key> inline
142  {
143  Array<Array<Key> > tmp(capacity_);
144 
145  for (int i=0; i<data_.length(); i++)
146  {
147  for (int j=0; j<data_[i].length(); j++)
148  {
149  int newIndex = hashCode(data_[i][j]) % capacity_;
150  tmp[newIndex].append(data_[i][j]);
151  }
152  }
153 
154  data_ = tmp;
155  }
156 
157  template<class Key> inline
159  {
160  Array<Key> rtn;
161  rtn.reserve(size());
162 
163  for (int i=0; i<data_.length(); i++)
164  {
165  for (int j=0; j<data_[i].length(); j++)
166  {
167  rtn.append(data_[i][j]);
168  }
169  }
170 
171  return rtn;
172  }
173 
174  template<class Key> inline
176  {
177  rtn.resize(0);
178 
179  for (int i=0; i<data_.length(); i++)
180  {
181  for (int j=0; j<data_[i].length(); j++)
182  {
183  rtn.append(data_[i][j]);
184  }
185  }
186  }
187 
188  template<class Key> inline
189  std::string HashSet<Key>::toString() const
190  {
191  std::string rtn = "HashSet[";
192 
193  bool first = true;
194 
195  for (int i=0; i<data_.length(); i++)
196  {
197  for (int j=0; j<data_[i].length(); j++)
198  {
199  if (!first) rtn += ", ";
200  first = false;
201  rtn += Teuchos::toString(data_[i][j]);
202  }
203  }
204  rtn += "]";
205  return rtn;
206  }
207 
208 
209  template<class Key> inline
210  void HashSet<Key>::remove(const Key& key)
211  {
212  TEUCHOS_TEST_FOR_EXCEPTION(!containsKey(key),
213  std::runtime_error,
214  "HashSet<Key>::remove: key "
215  << Teuchos::toString(key)
216  << " not found in HashSet"
217  << toString());
218 
219  count_--;
220  int h = hashCode(key) % capacity_;
221  Array<Key>& candidates = data_[h];
222 
223  for (int i=0; i<candidates.length(); i++)
224  {
225  if (candidates[i] == key)
226  {
227  candidates.remove(i);
228  break;
229  }
230  }
231  }
232 
233 
234 
235  template<class Key> inline
236  std::ostream& operator<<(std::ostream& os, const HashSet<Key>& h)
237  {
238  return os << h.toString();
239  }
240 
241 
242 }
243 
244 #endif // TEUCHOS_HASHSET_H
void remove(int i)
Remove the i-th element from the array, with optional boundschecking.
void reserve(size_type n)
Utilities for generating hashcodes. This is not a true hash ! For all ints and types less than ints i...
Array< T > & append(const T &x)
Add a new entry at the end of the array.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
bool containsKey(const Key &key) const
Check for the presence of a key.
Templated hashtable-based set.
static int nextPrime(int newCapacity)
std::string toString() const
Write to a std::string.
std::string toString(const HashSet< Key > &h)
Array< Array< Key > > data_
void resize(size_type new_size, const value_type &x=value_type())
HashSet(int capacity=19)
Create an empty HashSet.
void put(const Key &key)
Put a new object into the table.
Array< Key > arrayify() const
Get list of keys in Array form.
Templated array class derived from the STL std::vector.
int nextPrime(int newCap) const
int length() const
Return number of elements in the array.
int size() const
Get the number of elements in the table.
Utilities for generating hashcodes.
void remove(const Key &key)
Remove from the table the element given by key.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...