HashTable.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Class
25  Foam::HashTable
26 
27 Description
28  An STL-conforming hash table.
29 
30  Note:
31  Hashing index collisions are handled via chaining using a singly-linked
32  list with the colliding entry being added to the head of the linked
33  list. Thus copying the hash table (or indeed even resizing it) will
34  often result in a different hash order. Use a sorted table-of-contents
35  when the hash order is important.
36 
37 SourceFiles
38  HashTableI.H
39  HashTable.C
40  HashTableIO.C
41 
42 \*---------------------------------------------------------------------------*/
43 
44 #ifndef HashTable_H
45 #define HashTable_H
46 
47 #include "label.H"
48 #include "uLabel.H"
49 #include "word.H"
50 #include "className.H"
51 #include <initializer_list>
52 
53 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54 
55 namespace Foam
56 {
57 
58 // Forward declaration of friend functions and operators
59 
60 template<class T> class List;
61 template<class T> class UList;
62 template<class T, class Key, class Hash> class HashTable;
63 template<class T, class Key, class Hash> class HashPtrTable;
64 
65 template<class Type1, class Type2>
66 class Tuple2;
67 
68 template<class T, class Key, class Hash>
69 void writeEntry(Ostream& os, const HashTable<T, Key, Hash>& ht);
70 
71 template<class T, class Key, class Hash>
73 
74 template<class T, class Key, class Hash>
76 
77 
78 /*---------------------------------------------------------------------------*\
79  Class HashTableCore Declaration
80 \*---------------------------------------------------------------------------*/
81 
82 //- Template-invariant bits for HashTable
83 struct HashTableCore
84 {
85  //- Return a canonical (power-of-two) size
86  static label canonicalSize(const label);
87 
88  //- Maximum allowable table size
89  static const label maxTableSize;
90 
91  //- Construct null
93  {}
94 
95  //- Define template name and debug
96  ClassName("HashTable");
97 
98  //- A zero-sized end iterator
99  struct iteratorEnd
100  {
101  //- Construct null
102  iteratorEnd()
103  {}
104  };
105 
106  //- iteratorEnd set to beyond the end of any HashTable
107  inline static iteratorEnd cend()
108  {
109  return iteratorEnd();
110  }
111 
112  //- iteratorEnd set to beyond the end of any HashTable
113  inline static iteratorEnd end()
114  {
115  return iteratorEnd();
116  }
117 };
118 
119 
120 /*---------------------------------------------------------------------------*\
121  Class HashTable Declaration
122 \*---------------------------------------------------------------------------*/
123 
124 template<class T, class Key=word, class Hash=string::hash>
125 class HashTable
126 :
127  public HashTableCore
128 {
129  // Private Data type for table entries
130 
131  //- Structure to hold a hashed entry with SLList for collisions
132  struct hashedEntry
133  {
134  //- The lookup key
135  Key key_;
136 
137  //- Pointer to next hashedEntry in sub-list
138  hashedEntry* next_;
139 
140  //- The data object
141  T obj_;
142 
143  //- Construct from key, next pointer and object
144  inline hashedEntry(const Key&, hashedEntry* next, const T&);
145 
146  //- Disallow default bitwise copy construction
147  hashedEntry(const hashedEntry&) = delete;
148 
149  //- Disallow default bitwise assignment
150  void operator=(const hashedEntry&) = delete;
151  };
152 
153 
154  // Private Data: size of table, the table and current number of elements
155 
156  //- The current number of elements in table
157  label nElmts_;
158 
159  //- Number of primary entries allocated in table
160  label tableSize_;
161 
162  //- The table of primary entries
163  hashedEntry** table_;
164 
165 
166  // Private Member Functions
167 
168  //- Return a canonical (power-of-two) size
169  static label canonicalSize(const label);
170 
171  //- Return the hash index of the Key within the current table size.
172  // No checks for zero-sized tables.
173  inline label hashKeyIndex(const Key&) const;
174 
175  //- Assign a new hashedEntry to a possibly already existing key
176  bool set(const Key&, const T& newElmt, bool protect);
177 
178 
179 public:
180 
181  // Forward declaration of iterators
182 
183  class iteratorBase;
184  class iterator;
185  class const_iterator;
186 
187  //- Declare friendship with the HashPtrTable class
188  template<class T2, class Key2, class Hash2>
189  friend class HashPtrTable;
190 
191  //- Declare friendship with the iteratorBase
192  friend class iteratorBase;
193 
194  //- Declare friendship with the iterator
195  friend class iterator;
196 
197  //- Declare friendship with the const_iterator
198  friend class const_iterator;
199 
200 
201  // Constructors
202 
203  //- Construct given initial table size
204  HashTable(const label size = 128);
205 
206  //- Construct from Istream
207  HashTable(Istream&, const label size = 128);
208 
209  //- Construct from a list of keys and list of elements
210  // Lists must have equal length
211  HashTable(const UList<Key>& keyList, const UList<T>& elmtList);
212 
213  //- Copy constructor
215 
216  //- Move constructor
218 
219  //- Construct from an initialiser list
220  HashTable(std::initializer_list<Tuple2<Key, T>>);
221 
222 
223  //- Destructor
224  ~HashTable();
225 
226 
227  // Member Functions
228 
229  // Access
230 
231  //- The size of the underlying table
232  inline label capacity() const;
233 
234  //- Return number of elements in table
235  inline label size() const;
236 
237  //- Return true if the hash table is empty
238  inline bool empty() const;
239 
240  //- Return true if hashedEntry is found in table
241  bool found(const Key&) const;
242 
243  //- Find and return an iterator set at the hashedEntry
244  // If not found iterator = end()
245  iterator find(const Key&);
246 
247  //- Find and return an const_iterator set at the hashedEntry
248  // If not found iterator = end()
249  const_iterator find(const Key&) const;
250 
251  //- Return the table of contents
252  List<Key> toc() const;
253 
254  //- Return the table of contents as a sorted list
255  List<Key> sortedToc() const;
256 
257  //- Return a sorted list of constant iterators
259 
260  //- Print information
261  Ostream& printInfo(Ostream&) const;
262 
263 
264  // Edit
265 
266  //- Insert a new hashedEntry
267  inline bool insert(const Key&, const T& newElmt);
268 
269  //- Insert all the entries from the given HashTable
270  void insert(const HashTable<T, Key, Hash>&);
271 
272  //- Set a new hashedEntry, overwriting existing entries
273  inline bool set(const Key&, const T& newElmt);
274 
275  //- Insert all the entries from the given HashTable,
276  // overwriting existing entries
277  void set(const HashTable<T, Key, Hash>&);
278 
279  //- Erase a hashedEntry specified by given iterator
280  // This invalidates the iterator until the next operator++
281  bool erase(const iterator&);
282 
283  //- Erase a hashedEntry specified by the given key
284  bool erase(const Key&);
285 
286  //- Remove entries given by the listed keys from this HashTable
287  // Return the number of elements removed
288  label erase(const UList<Key>&);
289 
290  //- Remove entries given by the given keys from this HashTable
291  // Return the number of elements removed.
292  // The parameter HashTable needs the same type of key, but the
293  // type of values held and the hashing function are arbitrary.
294  template<class AnyType, class AnyHash>
296 
297  //- Resize the hash table for efficiency
298  void resize(const label newSize);
299 
300  //- Clear all entries from table
301  void clear();
302 
303  //- Clear the table entries and the table itself.
304  // Equivalent to clear() followed by resize(0)
305  void clearStorage();
306 
307  //- Shrink the allocated table to approx. twice number of elements
308  void shrink();
309 
310  //- Transfer the contents of the argument table into this table
311  // and annul the argument table.
313 
314 
315  // Member Operators
316 
317  //- Find and return a hashedEntry
318  inline T& operator[](const Key&);
319 
320  //- Find and return a hashedEntry
321  inline const T& operator[](const Key&) const;
322 
323  //- Find and return a hashedEntry, create it null if not present
324  inline T& operator()(const Key&);
325 
326  //- Assignment operator
327  void operator=(const HashTable<T, Key, Hash>&);
328 
329  //- Move assignment operator
331 
332  //- Assignment to an initialiser list
333  void operator=(std::initializer_list<Tuple2<Key, T>>);
334 
335  //- Equality. Hash tables are equal if the keys and values are equal.
336  // Independent of table storage size and table order.
337  bool operator==(const HashTable<T, Key, Hash>&) const;
338 
339  //- The opposite of the equality operation. Takes linear time.
340  bool operator!=(const HashTable<T, Key, Hash>&) const;
341 
342 
343 
344  // STL type definitions
345 
346  //- Type of values the HashTable contains.
347  typedef T value_type;
348 
349  //- Type that can be used for storing into HashTable::value_type
350  // objects. This type is usually List::value_type&.
351  typedef T& reference;
352 
353  //- Type that can be used for storing into constant
354  // HashTable::value_type objects. This type is usually const
355  // HashTable::value_type&.
356  typedef const T& const_reference;
357 
358  //- The type that can represent the size of a HashTable.
359  typedef label size_type;
360 
361 
362  // Iterators and helpers
363 
364  //- The iterator base for HashTable
365  // Note: data and functions are protected, to allow reuse by iterator
366  // and prevent most external usage.
367  // iterator and const_iterator have the same size, allowing
368  // us to reinterpret_cast between them (if desired)
369  class iteratorBase
370  {
371  // Private Data
372 
373  //- Pointer to the HashTable for which this is an iterator
374  // This also lets us use the default bitwise copy/assignment
375  HashTable<T, Key, Hash>* hashTable_;
376 
377  //- Current element
378  hashedEntry* entryPtr_;
379 
380  //- Current hash index
381  label hashIndex_;
382 
383 
384  protected:
385 
386  // Constructors
387 
388  //- Construct null - equivalent to an 'end' position
389  inline iteratorBase();
390 
391  //- Construct from hash table, moving to its 'begin' position
392  inline explicit iteratorBase
393  (
394  const HashTable<T, Key, Hash>* curHashTable
395  );
396 
397  //- Construct from hash table, element and hash index
398  inline iteratorBase
399  (
400  const HashTable<T, Key, Hash>* curHashTable,
401  const hashedEntry* elmt,
402  const label hashIndex
403  );
404 
405 
406  // Protected Member Functions
407 
408  //- Increment to the next position
409  inline void increment();
410 
411  //- Erase the HashTable element at the current position
412  bool erase();
413 
414  //- Return non-const access to referenced object
415  inline T& object();
416 
417  //- Return const access to referenced object
418  inline const T& cobject() const;
419 
420 
421  public:
422 
423  // Member Operators
424 
425  // Access
426 
427  //- Return the Key corresponding to the iterator
428  inline const Key& key() const;
429 
430  //- Compare hashedEntry element pointers
431  inline bool operator==(const iteratorBase&) const;
432  inline bool operator!=(const iteratorBase&) const;
433 
434  //- Compare hashedEntry to iteratorEnd pointers
435  inline bool operator==(const iteratorEnd& unused) const;
436  inline bool operator!=(const iteratorEnd& unused) const;
437  };
438 
439 
440  //- An STL-conforming iterator
441  class iterator
442  :
443  public iteratorBase
444  {
445  friend class HashTable;
446 
447  // Private Member Functions
448 
449  //- Construct from hash table, moving to its 'begin' position
450  inline explicit iterator
451  (
452  HashTable<T, Key, Hash>* curHashTable
453  );
454 
455  //- Construct from hash table, element and hash index
456  inline iterator
457  (
458  HashTable<T, Key, Hash>* curHashTable,
459  hashedEntry* elmt,
460  const label hashIndex
461  );
462 
463 
464  public:
465 
466  // Constructors
467 
468  //- Construct null (end iterator)
469  inline iterator();
470 
471  //- Construct end iterator
472  inline iterator(const iteratorEnd& unused);
473 
474 
475  // Member Operators
476 
477  //- Return referenced hash value
478  inline T& operator*();
479  inline T& operator()();
480 
481  //- Return referenced hash value
482  inline const T& operator*() const;
483  inline const T& operator()() const;
484 
485  inline iterator& operator++();
486  inline iterator operator++(int);
487  };
488 
489  //- Iterator set to the beginning of the HashTable
490  inline iterator begin();
491 
492 
493  // STL const_iterator
494 
495  //- An STL-conforming const_iterator
496  class const_iterator
497  :
498  public iteratorBase
499  {
500  friend class HashTable;
501 
502  // Private Member Functions
503 
504  //- Construct from hash table, moving to its 'begin' position
505  inline explicit const_iterator
506  (
507  const HashTable<T, Key, Hash>* curHashTable
508  );
509 
510  //- Construct from hash table, element and hash index
511  inline const_iterator
512  (
513  const HashTable<T, Key, Hash>* curHashTable,
514  const hashedEntry* elmt,
515  const label hashIndex
516  );
517 
518 
519  public:
520 
521  // Constructors
522 
523  //- Construct null (end iterator)
524  inline const_iterator();
525 
526  //- Construct from iterator
527  inline const_iterator(const iterator&);
528 
529  //- Construct end iterator
530  inline const_iterator(const iteratorEnd& unused);
531 
532 
533  // Member Operators
534 
535  //- Return referenced hash value
536  inline const T& operator*() const;
537  inline const T& operator()() const;
538 
539  inline const_iterator& operator++();
540  inline const_iterator operator++(int);
541 
542  };
543 
544 
545  //- const_iterator set to the beginning of the HashTable
546  inline const_iterator cbegin() const;
547 
548  //- const_iterator set to the beginning of the HashTable
549  inline const_iterator begin() const;
550 
551 
552  // IOstream Operator
553 
554  friend Istream& operator>> <T, Key, Hash>
555  (
556  Istream&,
558  );
559 
560  friend Ostream& operator<< <T, Key, Hash>
561  (
562  Ostream&,
564  );
565 };
566 
567 
568 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
569 
570 } // End namespace Foam
571 
572 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
573 
574  #include "HashTableI.H"
575 
576 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
577 
578 #ifndef NoHashTableC
579 #ifdef NoRepository
580  #include "HashTable.C"
581 #endif
582 #endif
583 
584 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
585 
586 #endif
587 
588 // ************************************************************************* //
A HashTable specialisation for hashing pointers.
Definition: HashPtrTable.H:67
An STL-conforming const_iterator.
Definition: HashTable.H:498
const T & operator*() const
Return referenced hash value.
Definition: HashTableI.H:470
const_iterator & operator++()
Definition: HashTableI.H:487
const_iterator()
Construct null (end iterator)
Definition: HashTableI.H:420
const T & operator()() const
Definition: HashTableI.H:478
The iterator base for HashTable.
Definition: HashTable.H:369
const T & cobject() const
Return const access to referenced object.
Definition: HashTableI.H:270
T & object()
Return non-const access to referenced object.
Definition: HashTableI.H:262
bool operator==(const iteratorBase &) const
Compare hashedEntry element pointers.
Definition: HashTableI.H:278
bool erase()
Erase the HashTable element at the current position.
Definition: HashTable.C:383
bool operator!=(const iteratorBase &) const
Definition: HashTableI.H:288
iteratorBase()
Construct null - equivalent to an 'end' position.
Definition: HashTableI.H:156
const Key & key() const
Return the Key corresponding to the iterator.
Definition: HashTableI.H:254
void increment()
Increment to the next position.
Definition: HashTableI.H:210
An STL-conforming iterator.
Definition: HashTable.H:443
T & operator*()
Return referenced hash value.
Definition: HashTableI.H:359
iterator()
Construct null (end iterator)
Definition: HashTableI.H:319
An STL-conforming hash table.
Definition: HashTable.H:127
List< const_iterator > sorted() const
Return a sorted list of constant iterators.
Definition: HashTable.C:253
List< Key > sortedToc() const
Return the table of contents as a sorted list.
Definition: HashTable.C:242
label size_type
The type that can represent the size of a HashTable.
Definition: HashTable.H:358
T & operator[](const Key &)
Find and return a hashedEntry.
Definition: HashTableI.H:103
bool erase(const iterator &)
Erase a hashedEntry specified by given iterator.
Definition: HashTable.C:445
void shrink()
Shrink the allocated table to approx. twice number of elements.
Definition: HashTable.C:574
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:227
T value_type
Type of values the HashTable contains.
Definition: HashTable.H:346
void transfer(HashTable< T, Key, Hash > &)
Transfer the contents of the argument table into this table.
Definition: HashTable.C:587
Ostream & printInfo(Ostream &) const
Print information.
Definition: HashTableIO.C:58
iterator begin()
Iterator set to the beginning of the HashTable.
Definition: HashTableI.H:411
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
Definition: HashTableI.H:506
label capacity() const
The size of the underlying table.
Definition: HashTableI.H:58
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
bool empty() const
Return true if the hash table is empty.
Definition: HashTableI.H:72
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:167
void clearStorage()
Clear the table entries and the table itself.
Definition: HashTable.C:566
bool operator!=(const HashTable< T, Key, Hash > &) const
The opposite of the equality operation. Takes linear time.
Definition: HashTable.C:709
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:138
T & reference
Type that can be used for storing into HashTable::value_type.
Definition: HashTable.H:350
~HashTable()
Destructor.
Definition: HashTable.C:125
void operator=(const HashTable< T, Key, Hash > &)
Assignment operator.
Definition: HashTable.C:611
T & operator()(const Key &)
Find and return a hashedEntry, create it null if not present.
Definition: HashTableI.H:137
bool operator==(const HashTable< T, Key, Hash > &) const
Equality. Hash tables are equal if the keys and values are equal.
Definition: HashTable.C:683
void clear()
Clear all entries from table.
Definition: HashTable.C:542
HashTable(const label size=128)
Construct given initial table size.
Definition: HashTable.C:36
void resize(const label newSize)
Resize the hash table for efficiency.
Definition: HashTable.C:506
const T & const_reference
Type that can be used for storing into constant.
Definition: HashTable.H:355
Hash function class for primitives. All non-primitives used to hash entries on hash tables likely nee...
Definition: Hash.H:53
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:66
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:74
Macro definitions for declaring ClassName(), NamespaceName(), etc.
Namespace for OpenFOAM.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
Definition: HashTableIO.C:96
Istream & operator>>(Istream &, pistonPointEdgeData &)
Ostream & operator<<(Ostream &os, const fvConstraints &constraints)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
A zero-sized end iterator.
Definition: HashTable.H:99
iteratorEnd()
Construct null.
Definition: HashTable.H:101
Template-invariant bits for HashTable.
Definition: HashTable.H:83
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:112
static label canonicalSize(const label)
Return a canonical (power-of-two) size.
Definition: HashTableCore.C:47
static iteratorEnd cend()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:106
static const label maxTableSize
Maximum allowable table size.
Definition: HashTable.H:88
HashTableCore()
Construct null.
Definition: HashTable.H:91
ClassName("HashTable")
Define template name and debug.