HashTableI.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-2015 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 \*---------------------------------------------------------------------------*/
25 
26 #include "error.H"
27 
28 // * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * //
29 
30 template<class T, class Key, class Hash>
32 (
33  const Key& key,
34  hashedEntry* next,
35  const T& obj
36 )
37 :
38  key_(key),
39  next_(next),
40  obj_(obj)
41 {}
42 
43 
44 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
45 
46 template<class T, class Key, class Hash>
47 inline Foam::label
49 {
50  // size is power of two - this is the modulus
51  return Hash()(key) & (tableSize_ - 1);
52 }
53 
54 
55 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
56 
57 template<class T, class Key, class Hash>
59 {
60  return tableSize_;
61 }
62 
63 
64 template<class T, class Key, class Hash>
66 {
67  return nElmts_;
68 }
69 
70 
71 template<class T, class Key, class Hash>
73 {
74  return !nElmts_;
75 }
76 
77 
78 template<class T, class Key, class Hash>
80 (
81  const Key& key,
82  const T& newEntry
83 )
84 {
85  return this->set(key, newEntry, true);
86 }
87 
88 
89 template<class T, class Key, class Hash>
91 (
92  const Key& key,
93  const T& newEntry
94 )
95 {
96  return this->set(key, newEntry, false);
97 }
98 
99 
100 template<class T, class Key, class Hash>
103 {
104  return xferMove(*this);
105 }
106 
107 
108 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
109 
110 template<class T, class Key, class Hash>
111 inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
112 {
113  iterator iter = this->find(key);
114 
115  if (iter == this->end())
116  {
118  << toc()
119  << exit(FatalError);
120  }
121 
122  return *iter;
123 }
124 
125 
126 template<class T, class Key, class Hash>
127 inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
128 {
129  const_iterator iter = this->find(key);
130 
131  if (iter == this->cend())
132  {
134  << toc()
135  << exit(FatalError);
136  }
137 
138  return *iter;
139 }
140 
141 
142 template<class T, class Key, class Hash>
144 {
145  iterator iter = this->find(key);
146 
147  if (iter == this->end())
148  {
149  this->insert(key, T());
150  return *find(key);
151  }
152  else
153  {
154  return *iter;
155  }
156 }
157 
158 
159 // * * * * * * * * * * * * * * * iterator base * * * * * * * * * * * * * * * //
160 
161 template<class T, class Key, class Hash>
163 :
164  hashTable_(0),
165  entryPtr_(0),
166  hashIndex_(0)
167 {}
168 
169 
170 template<class T, class Key, class Hash>
172 (
173  const HashTable<T, Key, Hash>* hashTbl
174 )
175 :
176  hashTable_(const_cast<HashTable<T, Key, Hash>*>(hashTbl)),
177  entryPtr_(0),
178  hashIndex_(0)
179 {
180  if (hashTable_->nElmts_)
181  {
182  // find first non-NULL table entry
183  while
184  (
185  !(entryPtr_ = hashTable_->table_[hashIndex_])
186  && ++hashIndex_ < hashTable_->tableSize_
187  )
188  {}
189 
190  if (hashIndex_ >= hashTable_->tableSize_)
191  {
192  // make into an end iterator
193  entryPtr_ = 0;
194  hashIndex_ = 0;
195  }
196  }
197 }
198 
199 
200 template<class T, class Key, class Hash>
202 (
203  const HashTable<T, Key, Hash>* hashTbl,
204  const hashedEntry* elmt,
205  const label hashIndex
206 )
207 :
208  hashTable_(const_cast<HashTable<T, Key, Hash>*>(hashTbl)),
209  entryPtr_(const_cast<hashedEntry*>(elmt)),
210  hashIndex_(hashIndex)
211 {}
212 
213 
214 template<class T, class Key, class Hash>
215 inline void
217 {
218  // A negative index is a special value from erase
219  if (hashIndex_ < 0)
220  {
221  // the markPos='-curPos-1', but we wish to continue at 'curPos-1'
222  // thus use '-(markPos+1) -1'
223  hashIndex_ = -(hashIndex_+1) - 1;
224  }
225  else if (entryPtr_)
226  {
227  if (entryPtr_->next_)
228  {
229  // Move to next element on the SLList
230  entryPtr_ = entryPtr_->next_;
231  return;
232  }
233  }
234  // else
235  // {
236  // // if we reach here (entryPtr_ is NULL) it is already at the end()
237  // // we should probably stop
238  // }
239 
240 
241  // Step to the next table entry
242  while
243  (
244  ++hashIndex_ < hashTable_->tableSize_
245  && !(entryPtr_ = hashTable_->table_[hashIndex_])
246  )
247  {}
248 
249  if (hashIndex_ >= hashTable_->tableSize_)
250  {
251  // make into an end iterator
252  entryPtr_ = 0;
253  hashIndex_ = 0;
254  }
255 }
256 
257 
258 template<class T, class Key, class Hash>
259 inline
261 {
262  return entryPtr_->key_;
263 }
264 
265 
266 template<class T, class Key, class Hash>
267 inline T&
269 {
270  return entryPtr_->obj_;
271 }
272 
273 
274 template<class T, class Key, class Hash>
275 inline const T&
277 {
278  return entryPtr_->obj_;
279 }
280 
281 
282 template<class T, class Key, class Hash>
284 (
285  const iteratorBase& iter
286 ) const
287 {
288  return entryPtr_ == iter.entryPtr_;
289 }
290 
291 
292 template<class T, class Key, class Hash>
294 (
295  const iteratorBase& iter
296 ) const
297 {
298  return entryPtr_ != iter.entryPtr_;
299 }
300 
301 
302 template<class T, class Key, class Hash>
304 (
305  const iteratorEnd&
306 ) const
307 {
308  return !entryPtr_;
309 }
310 
311 
312 template<class T, class Key, class Hash>
314 (
315  const iteratorEnd&
316 ) const
317 {
318  return entryPtr_;
319 }
320 
321 
322 // * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
323 
324 template<class T, class Key, class Hash>
326 :
327  iteratorBase()
328 {}
329 
330 
331 template<class T, class Key, class Hash>
333 (
334  const iteratorEnd&
335 )
336 :
337  iteratorBase()
338 {}
339 
340 
341 template<class T, class Key, class Hash>
343 (
344  HashTable<T, Key, Hash>* hashTbl
345 )
346 :
347  iteratorBase(hashTbl)
348 {}
349 
350 
351 template<class T, class Key, class Hash>
353 (
354  HashTable<T, Key, Hash>* hashTbl,
355  hashedEntry* elmt,
356  const label hashIndex
357 )
358 :
359  iteratorBase(hashTbl, elmt, hashIndex)
360 {}
361 
362 
363 template<class T, class Key, class Hash>
364 inline T&
366 {
367  return this->object();
368 }
369 
370 
371 template<class T, class Key, class Hash>
372 inline T&
374 {
375  return this->object();
376 }
377 
378 
379 template<class T, class Key, class Hash>
380 inline const T&
382 {
383  return this->cobject();
384 }
385 
386 
387 template<class T, class Key, class Hash>
388 inline const T&
390 {
391  return this->cobject();
392 }
393 
394 
395 template<class T, class Key, class Hash>
396 inline
399 {
400  this->increment();
401  return *this;
402 }
403 
404 
405 template<class T, class Key, class Hash>
408 {
409  iterator old = *this;
410  this->increment();
411  return old;
412 }
413 
414 
415 template<class T, class Key, class Hash>
418 {
419  return iterator(this);
420 }
421 
422 
423 // * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * //
424 
425 template<class T, class Key, class Hash>
427 :
428  iteratorBase()
429 {}
430 
431 
432 template<class T, class Key, class Hash>
434 (
436 )
437 :
438  iteratorBase(iter)
439 {}
440 
441 
442 template<class T, class Key, class Hash>
444 (
445  const iteratorEnd&
446 )
447 :
448  iteratorBase()
449 {}
450 
451 
452 template<class T, class Key, class Hash>
454 (
455  const HashTable<T, Key, Hash>* hashTbl
456 )
457 :
458  iteratorBase(hashTbl)
459 {}
460 
461 
462 template<class T, class Key, class Hash>
464 (
465  const HashTable<T, Key, Hash>* hashTbl,
466  const hashedEntry* elmt,
467  const label hashIndex
468 )
469 :
470  iteratorBase(hashTbl, elmt, hashIndex)
471 {}
472 
473 
474 template<class T, class Key, class Hash>
475 inline const T&
477 {
478  return this->cobject();
479 }
480 
481 
482 template<class T, class Key, class Hash>
483 inline const T&
485 {
486  return this->cobject();
487 }
488 
489 
490 template<class T, class Key, class Hash>
491 inline
494 {
495  this->increment();
496  return *this;
497 }
498 
499 
500 template<class T, class Key, class Hash>
503 {
504  const_iterator old = *this;
505  this->increment();
506  return old;
507 }
508 
509 
510 template<class T, class Key, class Hash>
513 {
514  return const_iterator(this);
515 }
516 
517 
518 template<class T, class Key, class Hash>
521 {
522  return this->cbegin();
523 }
524 
525 
526 // ************************************************************************* //
Foam::HashTable::iterator
friend class iterator
Declare friendship with the iterator.
Definition: HashTable.H:189
Foam::HashTable::iterator::operator*
T & operator*()
Return referenced hash value.
Definition: HashTableI.H:365
Foam::HashTable::operator[]
T & operator[](const Key &)
Find and return a hashedEntry.
Foam::HashTable::const_iterator::const_iterator
const_iterator()
Construct null (end iterator)
Definition: HashTableI.H:426
Foam::HashTable::iteratorBase::object
T & object()
Return non-const access to referenced object.
Definition: HashTableI.H:268
Foam::HashTable::iteratorBase
The iterator base for HashTable.
Definition: HashTable.H:343
Foam::HashTable::iteratorBase::increment
void increment()
Increment to the next position.
Definition: HashTableI.H:216
Foam::HashTable::iterator
An STL-conforming iterator.
Definition: HashTable.H:415
Foam::HashTable::const_iterator::operator*
const T & operator*() const
Return referenced hash value.
Definition: HashTableI.H:476
Foam::HashTable::const_iterator::operator()
const T & operator()() const
Definition: HashTableI.H:484
Foam::HashTable::iterator::operator++
iterator & operator++()
Definition: HashTableI.H:398
Foam::HashTable::cbegin
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
Definition: HashTableI.H:512
Foam::HashTable::const_iterator
An STL-conforming const_iterator.
Definition: HashTable.H:470
Foam::HashTable::iterator::operator()
T & operator()()
Definition: HashTableI.H:373
Foam::HashTable::capacity
label capacity() const
The size of the underlying table.
Definition: HashTableI.H:58
Foam::HashTable::insert
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
Foam::HashTable::iteratorBase::iteratorBase
iteratorBase()
Construct null - equivalent to an 'end' position.
Definition: HashTableI.H:162
Foam::HashTable::xfer
Xfer< HashTable< T, Key, Hash > > xfer()
Transfer contents to the Xfer container.
Definition: HashTableI.H:102
Foam::HashTable::hashKeyIndex
label hashKeyIndex(const Key &) const
Return the hash index of the Key within the current table size.
Definition: HashTableI.H:48
Foam::HashTable::HashTable
HashTable(const label size=128)
Construct given initial table size.
Foam::Xfer
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
Foam::HashTable::iteratorBase::entryPtr_
hashedEntry * entryPtr_
Current element.
Definition: HashTable.H:352
Foam::HashTable::const_iterator
friend class const_iterator
Declare friendship with the const_iterator.
Definition: HashTable.H:192
Foam::HashTable::const_iterator::operator++
const_iterator & operator++()
Definition: HashTableI.H:493
Foam::HashTable::set
bool set(const Key &, const T &newElmt, bool protect)
Assign a new hashedEntry to a possibly already existing key.
Foam::Hash
Hash function class for primitives. All non-primitives used to hash entries on hash tables likely nee...
Definition: Hash.H:56
Foam::label
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
error.H
Foam::HashTable::empty
bool empty() const
Return true if the hash table is empty.
Definition: HashTableI.H:72
Foam::HashTable::iteratorBase::cobject
const T & cobject() const
Return const access to referenced object.
Definition: HashTableI.H:276
Foam::HashTable::operator()
T & operator()(const Key &)
Find and return a hashedEntry, create it null if not present.
Definition: HashTableI.H:143
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:55
Foam::HashTable::iteratorBase
friend class iteratorBase
Declare friendship with the iteratorBase.
Definition: HashTable.H:186
Foam::HashTable::iteratorBase::hashTable_
HashTable< T, Key, Hash > * hashTable_
Pointer to the HashTable for which this is an iterator.
Definition: HashTable.H:349
Foam::FatalError
error FatalError
Foam::HashTable::size
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
Foam::HashTable::tableSize_
label tableSize_
Number of primary entries allocated in table.
Definition: HashTable.H:155
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::HashTable
An STL-conforming hash table.
Definition: HashTable.H:61
Foam::HashTable::iteratorBase::key
const Key & key() const
Return the Key corresponding to the iterator.
Definition: HashTableI.H:260
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
T
const volScalarField & T
Definition: createFields.H:25
Foam::HashTable::begin
iterator begin()
Iterator set to the beginning of the HashTable.
Definition: HashTableI.H:417
Foam::xferMove
Xfer< T > xferMove(T &)
Construct by transferring the contents of the arg.
Foam::HashTable::hashedEntry::hashedEntry
hashedEntry(const Key &, hashedEntry *next, const T &)
Construct from key, next pointer and object.
Foam::HashTable::iterator::iterator
iterator()
Construct null (end iterator)
Definition: HashTableI.H:325
insert
timeIndices insert(timeIndex, timeDirs[timeI].value())
Foam::HashTable::iteratorBase::hashIndex_
label hashIndex_
Current hash index.
Definition: HashTable.H:355