Teuchos - Trilinos Tools Package  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 
66  Array<Array<Key> > data_;
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
141  void HashSet<Key>::rehash()
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.
std::string toString() const
Write to a std::string.
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 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...