HashTable.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2016 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 "Xfer.H"
51 #include "className.H"
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 T, class Key, class Hash>
67 
68 template<class T, class Key, class Hash>
69 Ostream& operator<<(Ostream&, const HashTable<T, Key, Hash>&);
70 
71 
72 /*---------------------------------------------------------------------------*\
73  Class HashTableCore Declaration
74 \*---------------------------------------------------------------------------*/
75 
76 //- Template-invariant bits for HashTable
77 struct HashTableCore
78 {
79  //- Return a canonical (power-of-two) size
80  static label canonicalSize(const label);
81 
82  //- Maximum allowable table size
83  static const label maxTableSize;
84 
85  //- Construct null
87  {}
88 
89  //- Define template name and debug
90  ClassName("HashTable");
91 
92  //- A zero-sized end iterator
93  struct iteratorEnd
94  {
95  //- Construct null
96  iteratorEnd()
97  {}
98  };
99 
100  //- iteratorEnd set to beyond the end of any HashTable
101  inline static iteratorEnd cend()
102  {
103  return iteratorEnd();
104  }
105 
106  //- iteratorEnd set to beyond the end of any HashTable
107  inline static iteratorEnd end()
108  {
109  return iteratorEnd();
110  }
111 };
112 
113 
114 /*---------------------------------------------------------------------------*\
115  Class HashTable Declaration
116 \*---------------------------------------------------------------------------*/
117 
118 template<class T, class Key=word, class Hash=string::hash>
119 class HashTable
120 :
121  public HashTableCore
122 {
123  // Private data type for table entries
124 
125  //- Structure to hold a hashed entry with SLList for collisions
126  struct hashedEntry
127  {
128  //- The lookup key
129  Key key_;
130 
131  //- Pointer to next hashedEntry in sub-list
132  hashedEntry* next_;
133 
134  //- The data object
135  T obj_;
136 
137  //- Construct from key, next pointer and object
138  inline hashedEntry(const Key&, hashedEntry* next, const T&);
139 
140 
141  private:
142  //- Disallow default bitwise copy construct
143  hashedEntry(const hashedEntry&);
144 
145  //- Disallow default bitwise assignment
146  void operator=(const hashedEntry&);
147  };
148 
149 
150  // Private data: size of table, the table and current number of elements
151 
152  //- The current number of elements in table
153  label nElmts_;
154 
155  //- Number of primary entries allocated in table
156  label tableSize_;
157 
158  //- The table of primary entries
159  hashedEntry** table_;
160 
161 
162  // Private Member Functions
163 
164  //- Return a canonical (power-of-two) size
165  static label canonicalSize(const label);
166 
167  //- Return the hash index of the Key within the current table size.
168  // No checks for zero-sized tables.
169  inline label hashKeyIndex(const Key&) const;
170 
171  //- Assign a new hashedEntry to a possibly already existing key
172  bool set(const Key&, const T& newElmt, bool protect);
173 
174 public:
175 
176  // Forward declaration of iterators
177 
178  class iteratorBase;
179  class iterator;
180  class const_iterator;
181 
182  //- Declare friendship with the HashPtrTable class
183  template<class T2, class Key2, class Hash2>
184  friend class HashPtrTable;
185 
186  //- Declare friendship with the iteratorBase
187  friend class iteratorBase;
188 
189  //- Declare friendship with the iterator
190  friend class iterator;
191 
192  //- Declare friendship with the const_iterator
193  friend class const_iterator;
194 
195 
196  // Constructors
197 
198  //- Construct given initial table size
199  HashTable(const label size = 128);
200 
201  //- Construct from Istream
202  HashTable(Istream&, const label size = 128);
203 
204  //- Construct as copy
206 
207  //- Construct by transferring the parameter contents
209 
210 
211  //- Destructor
212  ~HashTable();
213 
214 
215  // Member Functions
216 
217  // Access
218 
219  //- The size of the underlying table
220  inline label capacity() const;
221 
222  //- Return number of elements in table
223  inline label size() const;
224 
225  //- Return true if the hash table is empty
226  inline bool empty() const;
227 
228  //- Return true if hashedEntry is found in table
229  bool found(const Key&) const;
230 
231  //- Find and return an iterator set at the hashedEntry
232  // If not found iterator = end()
233  iterator find(const Key&);
234 
235  //- Find and return an const_iterator set at the hashedEntry
236  // If not found iterator = end()
237  const_iterator find(const Key&) const;
238 
239  //- Return the table of contents
240  List<Key> toc() const;
241 
242  //- Return the table of contents as a sorted list
243  List<Key> sortedToc() const;
244 
245  //- Print information
246  Ostream& printInfo(Ostream&) const;
247 
248 
249  // Edit
250 
251  //- Insert a new hashedEntry
252  inline bool insert(const Key&, const T& newElmt);
253 
254  //- Assign a new hashedEntry, overwriting existing entries
255  inline bool set(const Key&, const T& newElmt);
256 
257  //- Erase a hashedEntry specified by given iterator
258  // This invalidates the iterator until the next operator++
259  bool erase(const iterator&);
260 
261  //- Erase a hashedEntry specified by the given key
262  bool erase(const Key&);
263 
264  //- Remove entries given by the listed keys from this HashTable
265  // Return the number of elements removed
266  label erase(const UList<Key>&);
267 
268  //- Remove entries given by the given keys from this HashTable
269  // Return the number of elements removed.
270  // The parameter HashTable needs the same type of key, but the
271  // type of values held and the hashing function are arbitrary.
272  template<class AnyType, class AnyHash>
274 
275  //- Resize the hash table for efficiency
276  void resize(const label newSize);
277 
278  //- Clear all entries from table
279  void clear();
280 
281  //- Clear the table entries and the table itself.
282  // Equivalent to clear() followed by resize(0)
283  void clearStorage();
284 
285  //- Shrink the allocated table to approx. twice number of elements
286  void shrink();
287 
288  //- Transfer the contents of the argument table into this table
289  // and annul the argument table.
290  void transfer(HashTable<T, Key, Hash>&);
291 
292  //- Transfer contents to the Xfer container
293  inline Xfer<HashTable<T, Key, Hash>> xfer();
294 
295 
296  // Member Operators
297 
298  //- Find and return a hashedEntry
299  inline T& operator[](const Key&);
300 
301  //- Find and return a hashedEntry
302  inline const T& operator[](const Key&) const;
303 
304  //- Find and return a hashedEntry, create it null if not present
305  inline T& operator()(const Key&);
306 
307  //- Assignment
308  void operator=(const HashTable<T, Key, Hash>&);
309 
310  //- Equality. Hash tables are equal if the keys and values are equal.
311  // Independent of table storage size and table order.
312  bool operator==(const HashTable<T, Key, Hash>&) const;
313 
314  //- The opposite of the equality operation. Takes linear time.
315  bool operator!=(const HashTable<T, Key, Hash>&) const;
316 
317 
318 
319  // STL type definitions
320 
321  //- Type of values the HashTable contains.
322  typedef T value_type;
323 
324  //- Type that can be used for storing into HashTable::value_type
325  // objects. This type is usually List::value_type&.
326  typedef T& reference;
327 
328  //- Type that can be used for storing into constant
329  // HashTable::value_type objects. This type is usually const
330  // HashTable::value_type&.
331  typedef const T& const_reference;
332 
333  //- The type that can represent the size of a HashTable.
334  typedef label size_type;
335 
336 
337  // Iterators and helpers
338 
339  //- The iterator base for HashTable
340  // Note: data and functions are protected, to allow reuse by iterator
341  // and prevent most external usage.
342  // iterator and const_iterator have the same size, allowing
343  // us to reinterpret_cast between them (if desired)
344  class iteratorBase
345  {
346  // Private Data
347 
348  //- Pointer to the HashTable for which this is an iterator
349  // This also lets us use the default bitwise copy/assignment
350  HashTable<T, Key, Hash>* hashTable_;
351 
352  //- Current element
353  hashedEntry* entryPtr_;
354 
355  //- Current hash index
356  label hashIndex_;
357 
358 
359  protected:
360 
361  // Constructors
362 
363  //- Construct null - equivalent to an 'end' position
364  inline iteratorBase();
365 
366  //- Construct from hash table, moving to its 'begin' position
367  inline explicit iteratorBase
368  (
369  const HashTable<T, Key, Hash>* curHashTable
370  );
371 
372  //- Construct from hash table, element and hash index
373  inline iteratorBase
374  (
375  const HashTable<T, Key, Hash>* curHashTable,
376  const hashedEntry* elmt,
377  const label hashIndex
378  );
379 
380 
381  // Protected Member Functions
382 
383  //- Increment to the next position
384  inline void increment();
385 
386  //- Erase the HashTable element at the current position
387  bool erase();
388 
389  //- Return non-const access to referenced object
390  inline T& object();
391 
392  //- Return const access to referenced object
393  inline const T& cobject() const;
394 
395 
396  public:
397 
398  // Member operators
399 
400  // Access
401 
402  //- Return the Key corresponding to the iterator
403  inline const Key& key() const;
404 
405  //- Compare hashedEntry element pointers
406  inline bool operator==(const iteratorBase&) const;
407  inline bool operator!=(const iteratorBase&) const;
408 
409  //- Compare hashedEntry to iteratorEnd pointers
410  inline bool operator==(const iteratorEnd& unused) const;
411  inline bool operator!=(const iteratorEnd& unused) const;
412  };
413 
414 
415  //- An STL-conforming iterator
416  class iterator
417  :
418  public iteratorBase
419  {
420  friend class HashTable;
421 
422  // Private Member Functions
423 
424  //- Construct from hash table, moving to its 'begin' position
425  inline explicit iterator
426  (
427  HashTable<T, Key, Hash>* curHashTable
428  );
429 
430  //- Construct from hash table, element and hash index
431  inline iterator
432  (
433  HashTable<T, Key, Hash>* curHashTable,
434  hashedEntry* elmt,
435  const label hashIndex
436  );
437 
438 
439  public:
440 
441  // Constructors
442 
443  //- Construct null (end iterator)
444  inline iterator();
445 
446  //- Construct end iterator
447  inline iterator(const iteratorEnd& unused);
448 
449 
450  // Member operators
451 
452  //- Return referenced hash value
453  inline T& operator*();
454  inline T& operator()();
455 
456  //- Return referenced hash value
457  inline const T& operator*() const;
458  inline const T& operator()() const;
459 
460  inline iterator& operator++();
461  inline iterator operator++(int);
462  };
463 
464  //- Iterator set to the beginning of the HashTable
465  inline iterator begin();
466 
467 
468  // STL const_iterator
469 
470  //- An STL-conforming const_iterator
471  class const_iterator
472  :
473  public iteratorBase
474  {
475  friend class HashTable;
476 
477  // Private Member Functions
478 
479  //- Construct from hash table, moving to its 'begin' position
480  inline explicit const_iterator
481  (
482  const HashTable<T, Key, Hash>* curHashTable
483  );
484 
485  //- Construct from hash table, element and hash index
486  inline const_iterator
487  (
488  const HashTable<T, Key, Hash>* curHashTable,
489  const hashedEntry* elmt,
490  const label hashIndex
491  );
492 
493 
494  public:
495 
496  // Constructors
497 
498  //- Construct null (end iterator)
499  inline const_iterator();
500 
501  //- Construct from iterator
502  inline const_iterator(const iterator&);
503 
504  //- Construct end iterator
505  inline const_iterator(const iteratorEnd& unused);
506 
507 
508  // Member operators
509 
510  //- Return referenced hash value
511  inline const T& operator*() const;
512  inline const T& operator()() const;
513 
514  inline const_iterator& operator++();
515  inline const_iterator operator++(int);
516 
517  };
518 
519 
520  //- const_iterator set to the beginning of the HashTable
521  inline const_iterator cbegin() const;
522 
523  //- const_iterator set to the beginning of the HashTable
524  inline const_iterator begin() const;
525 
526 
527  // IOstream Operator
528 
529  friend Istream& operator>> <T, Key, Hash>
530  (
531  Istream&,
533  );
534 
535  friend Ostream& operator<< <T, Key, Hash>
536  (
537  Ostream&,
539  );
540 };
541 
542 
543 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
544 
545 } // End namespace Foam
546 
547 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
548 
549  #include "HashTableI.H"
550 
551 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
552 
553 #ifndef NoHashTableC
554 #ifdef NoRepository
555  #include "HashTable.C"
556 #endif
557 #endif
558 
559 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
560 
561 #endif
562 
563 // ************************************************************************* //
A zero-sized end iterator.
Definition: HashTable.H:92
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
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
An STL-conforming const_iterator.
Definition: HashTable.H:470
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:106
srcOptions erase("case")
tUEqn clear()
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
ClassName("HashTable")
Define template name and debug.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
tmp< fvMatrix< Type > > operator*(const DimensionedField< scalar, volMesh > &, const fvMatrix< Type > &)
A HashTable specialization for hashing pointers.
Definition: HashPtrTable.H:50
HashTableCore()
Construct null.
Definition: HashTable.H:85
An STL-conforming iterator.
Definition: HashTable.H:415
tmp< fvMatrix< Type > > operator==(const fvMatrix< Type > &, const fvMatrix< Type > &)
Istream & operator>>(Istream &, directionInfo &)
timeIndices insert(timeIndex, timeDirs[timeI].value())
triSurfaceToAgglom resize(surfacesMesh.size())
static const label maxTableSize
Maximum allowable table size.
Definition: HashTable.H:82
An STL-conforming hash table.
Definition: HashTable.H:61
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Template-invariant bits for HashTable.
Definition: HashTable.H:76
static label canonicalSize(const label)
Return a canonical (power-of-two) size.
Definition: HashTableCore.C:47
Macro definitions for declaring ClassName(), NamespaceName(), etc.
Hash function class for primitives. All non-primitives used to hash entries on hash tables likely nee...
Definition: Hash.H:54
Single incompressible phase derived from the phase-fraction. Used as part of the multiPhaseMixture fo...
Definition: phase.H:52
iteratorEnd()
Construct null.
Definition: HashTable.H:95
bool operator!=(const particle &, const particle &)
Definition: particle.C:145
bool found
The iterator base for HashTable.
Definition: HashTable.H:343
static iteratorEnd cend()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:100
Namespace for OpenFOAM.