HashTable.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2024 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #ifndef Foam_HashTable_C
30 #define Foam_HashTable_C
31 
32 #include "HashTable.H"
33 #include "List.H"
34 #include "FixedList.H"
35 #include "UPtrList.H"
36 
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
38 
39 template<class T, class Key, class Hash>
41 :
42  HashTableCore(),
43  size_(0),
44  capacity_(0),
45  table_(nullptr)
46 {}
47 
48 
49 template<class T, class Key, class Hash>
51 :
53 {}
54 
55 
56 template<class T, class Key, class Hash>
57 Foam::HashTable<T, Key, Hash>::HashTable(const label initialCapacity)
58 :
59  HashTable<T, Key, Hash>()
60 {
61  if (initialCapacity > 0)
62  {
63  // Like resize() but no initial content to transfer
64  capacity_ = HashTableCore::canonicalSize(initialCapacity);
65  table_ = new node_type*[capacity_];
66  std::fill_n(table_, capacity_, static_cast<node_type*>(nullptr));
67  }
68 }
69 
70 
71 template<class T, class Key, class Hash>
72 Foam::HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
73 :
74  HashTable<T, Key, Hash>(2*ht.size())
75 {
76  for (const_iterator iter = ht.cbegin(); iter != ht.cend(); ++iter)
77  {
78  insert(iter.key(), iter.val());
79  }
80 }
81 
82 
83 template<class T, class Key, class Hash>
84 Foam::HashTable<T, Key, Hash>::HashTable(HashTable<T, Key, Hash>&& rhs) noexcept
85 :
86  HashTableCore(),
87  size_(rhs.size_),
88  capacity_(rhs.capacity_),
89  table_(rhs.table_)
90 {
91  // Stole all contents
92  rhs.size_ = 0;
93  rhs.capacity_ = 0;
94  rhs.table_ = nullptr;
95 }
96 
97 
98 template<class T, class Key, class Hash>
100 (
101  std::initializer_list<std::pair<Key, T>> list,
102  const bool overwrite
103 )
104 :
105  HashTable<T, Key, Hash>()
106 {
107  reserve(list.size());
108 
109  for (const auto& keyval : list)
110  {
111  this->setEntry(overwrite, keyval.first, keyval.second);
112  }
113 }
114 
115 
116 template<class T, class Key, class Hash>
118 (
119  const UList<Key>& keys,
120  const UList<T>& values,
121  const bool overwrite
122 )
123 :
124  HashTable<T, Key, Hash>()
125 {
126  const label len = std::min(keys.size(), values.size());
127 
128  reserve(len);
129 
130  for (label i = 0; i < len; ++i)
131  {
132  this->setEntry(overwrite, keys[i], values[i]);
133  }
134 }
135 
136 
137 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
138 
139 template<class T, class Key, class Hash>
141 {
142  // Remove all entries from table
143  clear();
144 
145  // Remove the table itself
146  capacity_ = 0;
147  delete[] table_;
148  table_ = nullptr;
149 }
150 
151 
152 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
153 
154 template<class T, class Key, class Hash>
156 {
157  List<Key> list(size_);
158  label count = 0;
159 
160  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
161  {
162  list[count++] = iter.key();
163  }
164 
165  return list;
166 }
167 
168 
169 template<class T, class Key, class Hash>
171 {
172  List<Key> list(this->toc());
173  Foam::sort(list);
174 
175  return list;
176 }
177 
178 
179 template<class T, class Key, class Hash>
180 template<class Compare>
182 (
183  const Compare& comp
184 ) const
185 {
186  List<Key> list(this->toc());
187  Foam::sort(list, comp);
189  return list;
190 }
191 
192 
193 template<class T, class Key, class Hash>
196 {
197  UPtrList<const node_type> result(size_);
198 
199  label count = 0;
200 
201  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
202  {
203  result.set(count++, iter.node());
204  }
205 
206  Foam::sort(result);
208  return result;
209 }
210 
211 
212 template<class T, class Key, class Hash>
215 {
216  UPtrList<node_type> result(size_);
217 
218  label count = 0;
219 
220  for (iterator iter = begin(); iter != end(); ++iter)
221  {
222  result.set(count++, iter.node());
223  }
224 
225  Foam::sort(result);
226 
227  return result;
228 }
229 
230 
231 
232 template<class T, class Key, class Hash>
233 template<class UnaryPredicate>
235 (
236  const UnaryPredicate& pred,
237  const bool invert
238 ) const
239 {
240  List<Key> list(size_);
241  label count = 0;
242 
243  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
244  {
245  if ((pred(iter.key()) ? !invert : invert))
246  {
247  list[count++] = iter.key();
248  }
249  }
250 
251  list.resize(count);
252  Foam::sort(list);
253 
254  return list;
255 }
256 
257 
258 template<class T, class Key, class Hash>
259 template<class UnaryPredicate>
261 (
262  const UnaryPredicate& pred,
263  const bool invert
264 ) const
265 {
266  List<Key> list(size_);
267  label count = 0;
268 
269  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
270  {
271  if ((pred(iter.val()) ? !invert : invert))
272  {
273  list[count++] = iter.key();
274  }
275  }
276 
277  list.resize(count);
278  Foam::sort(list);
279 
280  return list;
281 }
282 
283 
284 template<class T, class Key, class Hash>
285 template<class BinaryPredicate>
287 (
288  const BinaryPredicate& pred,
289  const bool invert
290 ) const
291 {
292  List<Key> list(size_);
293  label count = 0;
294 
295  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
296  {
297  if ((pred(iter.key(), iter.val()) ? !invert : invert))
298  {
299  list[count++] = iter.key();
300  }
301  }
302 
303  list.resize(count);
304  Foam::sort(list);
305 
306  return list;
307 }
308 
309 
310 template<class T, class Key, class Hash>
311 template<class UnaryPredicate>
313 (
314  const UnaryPredicate& pred,
315  const bool invert
316 ) const
317 {
318  label count = 0;
319 
320  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
321  {
322  if ((pred(iter.key()) ? !invert : invert))
323  {
324  ++count;
325  }
326  }
327 
328  return count;
329 }
330 
331 
332 template<class T, class Key, class Hash>
333 template<class UnaryPredicate>
335 (
336  const UnaryPredicate& pred,
337  const bool invert
338 ) const
339 {
340  label count = 0;
341 
342  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
343  {
344  if ((pred(iter.val()) ? !invert : invert))
345  {
346  ++count;
347  }
348  }
349 
350  return count;
351 }
352 
353 
354 template<class T, class Key, class Hash>
355 template<class BinaryPredicate>
357 (
358  const BinaryPredicate& pred,
359  const bool invert
360 ) const
361 {
362  label count = 0;
363 
364  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
365  {
366  if ((pred(iter.key(), iter.val()) ? !invert : invert))
367  {
368  ++count;
369  }
370  }
371 
372  return count;
373 }
374 
375 
376 template<class T, class Key, class Hash>
377 template<class... Args>
379 (
380  const bool overwrite,
381  const Key& key,
382  Args&&... args
383 )
384 {
385  if (!capacity_)
386  {
387  setCapacity(128); // Impose an initial capacity
388  }
389 
390  const label index = hashKeyIndex(key);
391 
392  node_type* curr = nullptr;
393  node_type* prev = nullptr;
394 
395  for (node_type* ep = table_[index]; ep; ep = ep->next_)
396  {
397  if (key == ep->key())
398  {
399  curr = ep;
400  break;
401  }
402  prev = ep;
403  }
404 
405  if (!curr)
406  {
407  // Not found, insert it at the head
408  table_[index] =
409  new node_type(table_[index], key, std::forward<Args>(args)...);
410 
411  ++size_;
412  if (0.8*capacity_ < size_) // Resize after 0.8 load factor
413  {
414  if (capacity_ < maxTableSize) setCapacity(2*capacity_);
415  }
416  }
417  else if (overwrite)
418  {
419  // Overwrite current entry (Perl convention).
420 
421  // Can skip if the value is not stored anyhow (Eg, HashSet)
422  // - this avoids a useless delete/new
423  if (!node_type::stores_value())
424  {
425  return true;
426  }
427 
428  node_type* ep = curr->next_; // next in the linked list
429 
430  // In some cases the delete/new could be avoided in favour of move
431  // assignment, but cannot be certain that all objects support this
432  // or that it behaves the same as a copy construct.
433 
434  delete curr;
435  ep = new node_type(ep, key, std::forward<Args>(args)...);
436 
437  // Replace current element - within list or insert at the head
438  if (prev)
439  {
440  prev->next_ = ep;
441  }
442  else
443  {
444  table_[index] = ep;
445  }
446  }
447  else
448  {
449  // Not overwriting existing entry
450  return false;
451  }
452 
453  return true;
454 }
455 
456 
457 template<class T, class Key, class Hash>
458 void Foam::HashTable<T, Key, Hash>::insert_node(node_type* entry)
459 {
460  if (!entry) return;
461 
462  if (!capacity_)
463  {
464  setCapacity(128); // Impose an initial capacity
465  }
466 
467  const label index = hashKeyIndex(entry->key());
468 
469  node_type* curr = nullptr;
470  //node_type* prev = nullptr;
471 
472  for (node_type* ep = table_[index]; ep; ep = ep->next_)
473  {
474  if (entry->key() == ep->key())
475  {
476  curr = ep;
477  break;
478  }
479  //prev = ep;
480  }
481 
482  if (!curr)
483  {
484  // Not found, insert it at the head
485  table_[index] = entry;
486 
487  ++size_;
488  if (0.8*capacity_ < size_) // Resize after 80% fill factor
489  {
490  if (capacity_ < maxTableSize) setCapacity(2*capacity_);
491  }
492  }
493  else
494  {
496  << "Not inserting " << entry->key() << ": already in table\n"
497  << exit(FatalError);
498  }
499 }
500 
501 
502 template<class T, class Key, class Hash>
503 bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter)
504 {
505  // NOTE: we use (const iterator&) here, but treat its contents as mutable.
506  //
507  // The parameter should be (iterator&), but then the compiler doesn't find
508  // it correctly and tries to call as (iterator) instead.
509 
510  return iterator_erase(const_cast<iterator&>(iter));
511 }
512 
513 
514 template<class T, class Key, class Hash>
516 {
517  if (size_)
518  {
519  iterator iter(find(key));
520  if (iter.good()) return iterator_erase(iter);
521  }
522  return false;
523 }
524 
525 
526 template<class T, class Key, class Hash>
527 template<class InputIter>
528 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
529 (
530  InputIter first,
531  InputIter last
532 )
533 {
534  label changed = 0;
535 
536  for
537  (
538  const label nTotal = this->size();
539  changed < nTotal && first != last; // terminate early
540  ++first
541  )
542  {
543  if (this->erase(*first))
544  {
545  ++changed;
546  }
547  }
549  return changed;
550 }
551 
552 
553 template<class T, class Key, class Hash>
554 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
555 (
556  std::initializer_list<Key> keys
557 )
558 {
559  return erase(keys.begin(), keys.end());
560 }
561 
562 
563 template<class T, class Key, class Hash>
564 template<unsigned N>
565 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
566 (
567  const FixedList<Key, N>& keys
568 )
569 {
570  return erase(keys.cbegin(), keys.cend());
571 }
572 
573 
574 template<class T, class Key, class Hash>
575 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
576 (
577  const UList<Key>& keys
578 )
579 {
580  return erase(keys.cbegin(), keys.cend());
581 }
582 
583 
584 template<class T, class Key, class Hash>
585 template<class AnyType, class AnyHash>
587 (
589 )
590 {
591  const label nTotal = this->size();
592  label changed = 0;
593 
594  if (other.size() <= nTotal)
595  {
596  // The other is smaller/same-size, use its keys for removal
597 
598  for
599  (
600  auto iter = other.cbegin();
601  changed < nTotal && iter != other.cend(); // Terminate early
602  ++iter
603  )
604  {
605  if (erase(iter.key()))
606  {
607  ++changed;
608  }
609  }
610  }
611  else
612  {
613  // We are smaller: remove if found in the other hash
614  for
615  (
616  iterator iter = begin();
617  changed < nTotal && iter != end(); // Terminate early
618  ++iter
619  )
620  {
621  if (other.contains(iter.key()) && erase(iter))
622  {
623  ++changed;
624  }
625  }
626  }
627 
628  return changed;
629 }
630 
631 
632 template<class T, class Key, class Hash>
633 template<class AnyType, class AnyHash>
635 (
637 )
638 {
639  const label nTotal = this->size();
640  label changed = 0;
641 
642  if (other.empty())
643  {
644  // Trivial case
645  changed = nTotal;
646  this->clear();
647  }
648  else
649  {
650  // Inverted logic: remove if *not* found in the other hash
651 
652  for (iterator iter = begin(); iter != end(); ++iter)
653  {
654  if (!other.contains(iter.key()) && erase(iter))
655  {
656  ++changed;
657  }
658  }
659  }
660 
661  return changed;
662 }
663 
664 
665 template<class T, class Key, class Hash>
666 void Foam::HashTable<T, Key, Hash>::setCapacity(label newCapacity)
667 {
668  newCapacity = HashTableCore::canonicalSize(newCapacity);
669 
670  if (newCapacity == capacity_)
671  {
672  return;
673  }
674 
675  if (!size_)
676  {
677  // Table is unpopulated - can already remove now
678  capacity_ = 0;
679  delete[] table_;
680  table_ = nullptr;
681  }
682 
683  if (!newCapacity)
684  {
685  // Special handling for capacity = 0.
686  if (size_)
687  {
689  << "HashTable contains " << size_
690  << " elements, cannot set capacity to 0 buckets!" << nl;
691  }
692  return;
693  }
694 
695  // Swap primary table entries: size_ is left untouched
696 
697  auto oldTable = table_;
698  const label oldCapacity = capacity_;
699 
700  capacity_ = newCapacity;
701  table_ = new node_type*[capacity_];
702  std::fill_n(table_, capacity_, static_cast<node_type*>(nullptr));
703 
704  if (!oldTable)
705  {
706  return;
707  }
708 
709  // Move to new table[] but with new chaining.
710 
711  for (label i = 0, pending = size_; pending && i < oldCapacity; ++i)
712  {
713  for (node_type* ep = oldTable[i]; ep; /*nil*/)
714  {
715  node_type* next = ep->next_;
716 
717  // Move to new location
718  {
719  const label newIdx = hashKeyIndex(ep->key());
720 
721  ep->next_ = table_[newIdx]; // add to head
722  table_[newIdx] = ep;
723  }
724 
725  ep = next; // continue in the linked-list
726  --pending; // note any early completion
727  }
728  oldTable[i] = nullptr;
729  }
730 
731  delete[] oldTable;
732 }
733 
734 
735 template<class T, class Key, class Hash>
737 {
738  setCapacity(newCapacity);
739 }
740 
741 
742 template<class T, class Key, class Hash>
743 void Foam::HashTable<T, Key, Hash>::reserve(label numEntries)
744 {
745  if (numEntries > size_)
746  {
747  // From number of entries to estimated capacity
748  // - initial load factor of 0.5
749  numEntries *= 2;
750  if (numEntries > capacity_) setCapacity(numEntries);
751  }
752 }
753 
754 
755 template<class T, class Key, class Hash>
757 {
758  if (!table_)
759  {
760  capacity_ = 0; // Paranoid
761  }
762 
763  for (label i = 0, pending = size_; pending && i < capacity_; ++i)
764  {
765  for (node_type* ep = table_[i]; ep; /*nil*/)
766  {
767  node_type* next = ep->next_;
768 
769  delete ep;
770 
771  ep = next; // continue in the linked-list
772  --pending; // note any early completion
773  }
774  table_[i] = nullptr;
775  }
776  size_ = 0;
777 }
778 
779 
780 template<class T, class Key, class Hash>
782 {
783  // Remove all entries from table
784  clear();
785 
786  // Remove the table itself
787  capacity_ = 0;
788  delete[] table_;
789  table_ = nullptr;
790 }
791 
792 
793 template<class T, class Key, class Hash>
795 {
796  if (this == &rhs)
797  {
798  return; // Self-swap is a no-op
799  }
800 
801  std::swap(size_, rhs.size_);
802  std::swap(capacity_, rhs.capacity_);
803  std::swap(table_, rhs.table_);
804 }
805 
806 
807 template<class T, class Key, class Hash>
809 {
810  if (this == &rhs)
811  {
812  return; // Self-assignment is a no-op
813  }
814 
815  clear();
816  swap(rhs);
817 }
818 
819 
820 template<class T, class Key, class Hash>
821 template<class UnaryPredicate>
823 (
824  const UnaryPredicate& pred,
825  const bool pruning
826 )
827 {
828  label changed = 0;
829 
830  for (iterator iter = begin(); iter != end(); ++iter)
831  {
832  // Matches? either prune (pruning) or keep (!pruning)
833  if
834  (
835  (pred(iter.key()) ? pruning : !pruning)
836  && erase(iter)
837  )
838  {
839  ++changed;
840  }
841  }
842 
843  return changed;
844 }
845 
846 
847 template<class T, class Key, class Hash>
848 template<class UnaryPredicate>
850 (
851  const UnaryPredicate& pred,
852  const bool pruning
853 )
854 {
855  label changed = 0;
856 
857  for (iterator iter = begin(); iter != end(); ++iter)
858  {
859  // Matches? either prune (pruning) or keep (!pruning)
860  if
861  (
862  (pred(iter.val()) ? pruning : !pruning)
863  && erase(iter)
864  )
865  {
866  ++changed;
867  }
868  }
869 
870  return changed;
871 }
872 
873 
874 template<class T, class Key, class Hash>
875 template<class BinaryPredicate>
877 (
878  const BinaryPredicate& pred,
879  const bool pruning
880 )
881 {
882  label changed = 0;
883 
884  for (iterator iter = begin(); iter != end(); ++iter)
885  {
886  // Matches? either prune (pruning) or keep (!pruning)
887  if
888  (
889  (pred(iter.key(), iter.val()) ? pruning : !pruning)
890  && erase(iter)
891  )
892  {
893  ++changed;
894  }
895  }
896 
897  return changed;
898 }
899 
900 
901 template<class T, class Key, class Hash>
902 void Foam::HashTable<T, Key, Hash>::merge(HashTable<T, Key, Hash>& source)
903 {
904  // Self-merge implicitly a no-op
905 
906  if (node_type::stores_value())
907  {
908  // key/val pair
909  for (iterator iter = source.begin(); iter != source.end(); ++iter)
910  {
911  if (!contains(iter.key()))
912  {
913  node_type* entry = source.iterator_extract(iter);
914  this->insert_node(entry);
915  }
916  }
917  }
918  else
919  {
920  // key only, does not store a value.
921  // Since the key is const, juggling the node does not work
922 
923  for (iterator iter = source.begin(); iter != source.end(); ++iter)
924  {
925  if (emplace(iter.key()))
926  {
927  source.erase(iter);
928  }
929  }
930  }
931 }
932 
933 
934 template<class T, class Key, class Hash>
935 void Foam::HashTable<T, Key, Hash>::merge(HashTable<T, Key, Hash>&& source)
936 {
937  merge(source);
938 }
939 
940 
941 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
942 
943 template<class T, class Key, class Hash>
945 (
946  const HashTable<T, Key, Hash>& rhs
947 )
948 {
949  if (this == &rhs)
950  {
951  return; // Self-assignment is a no-op
952  }
953 
954  this->clear();
955  this->reserve(rhs.size());
956 
957  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
958  {
959  insert(iter.key(), iter.val());
960  }
961 }
962 
963 
964 template<class T, class Key, class Hash>
966 (
967  std::initializer_list<std::pair<Key, T>> rhs
968 )
969 {
970  this->clear();
971  this->reserve(rhs.size());
972 
973  for (const auto& keyval : rhs)
974  {
975  set(keyval.first, keyval.second);
976  }
977 }
978 
979 
980 template<class T, class Key, class Hash>
982 (
983  HashTable<T, Key, Hash>&& rhs
984 )
985 {
986  transfer(rhs); // Includes self-assignment check
987 }
988 
989 
990 template<class T, class Key, class Hash>
992 (
993  const HashTable<T, Key, Hash>& rhs
994 ) const
995 {
996  // Sizes (number of keys) must match
997  if (size() != rhs.size())
998  {
999  return false;
1000  }
1001 
1002  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
1003  {
1004  const const_iterator other(this->cfind(iter.key()));
1005 
1006  if (!other.good() || other.val() != iter.val())
1007  {
1008  return false;
1009  }
1010  }
1012  return true;
1013 }
1014 
1015 
1016 template<class T, class Key, class Hash>
1018 (
1019  const HashTable<T, Key, Hash>& rhs
1020 ) const
1022  return !operator==(rhs);
1023 }
1024 
1025 
1026 template<class T, class Key, class Hash>
1028 (
1029  const HashTable<T, Key, Hash>& rhs
1030 )
1031 {
1032  // Avoid no-ops:
1033  if (rhs.size() && (this != &rhs))
1034  {
1035  if (this->size())
1036  {
1037  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
1038  {
1039  insert(iter.key(), iter.val());
1040  }
1041  }
1042  else
1043  {
1044  (*this) = rhs;
1045  }
1046  }
1047 
1048  return *this;
1049 }
1050 
1051 
1052 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1053 
1054 // Iterators, Friend Operators
1055 
1056 #include "HashTableIter.C"
1057 #include "HashTableIO.C"
1058 
1059 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1060 
1061 #endif
1062 
1063 // ************************************************************************* //
label countValues(const UnaryPredicate &pred, const bool invert=false) const
Count the number of values that satisfy the unary predicate.
label find(const ListType &input, const UnaryPredicate &pred, const label start=0)
Same as ListOps::find_if.
Definition: ListOps.H:827
List< Key > tocKeys(const UnaryPredicate &pred, const bool invert=false) const
The table of contents (the keys) selected according to the unary predicate applied to the keys...
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant UList.
Definition: UListI.H:450
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
label filterValues(const UnaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their values.
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:107
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:153
srcOptions erase("case")
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
label retain(const HashTable< AnyType, Key, AnyHash > &other)
Retain table entries given by keys of the other hash-table.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
srcOptions insert("case", fileName(rootDirSource/caseDirSource))
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
UPtrList< const node_type > csorted() const
Const access to the hash-table contents in sorted order (sorted by keys).
Definition: HashTable.C:188
void setCapacity(label newCapacity)
Change the hash table capacity (number of buckets).
Definition: HashTable.C:659
HashTable() noexcept
Default construct: empty without allocation (capacity=0)
Definition: HashTable.C:33
UPtrList< node_type > sorted()
Non-const access to the hash-table contents in sorted order (sorted by keys).
Definition: HashTable.C:207
List< Key > tocEntries(const BinaryPredicate &pred, const bool invert=false) const
The table of contents (the keys) selected according to the binary predicate applied to the keys and v...
~HashTable()
Destructor.
Definition: HashTable.C:133
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:358
label countEntries(const BinaryPredicate &pred, const bool invert=false) const
Count the number of entries that satisfy the binary predicate.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
bool contains(const Key &key) const
True if hashed key is contained (found) in table.
Definition: HashTableI.H:72
label filterEntries(const BinaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their key/value.
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:296
void clear()
Remove all entries from table.
Definition: HashTable.C:749
constexpr auto cend(const C &c) -> decltype(c.end())
Return const_iterator to the end of the container c.
Definition: stdFoam.H:223
label countKeys(const UnaryPredicate &pred, const bool invert=false) const
Count the number of keys that satisfy the unary predicate.
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
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:105
void resize(label newCapacity)
Rehash the hash table with new number of buckets. Currently identical to setCapacity() ...
Definition: HashTable.C:729
const direction noexcept
Definition: Scalar.H:258
bool empty() const noexcept
True if the hash table is empty.
Definition: HashTable.H:353
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:201
constexpr auto cbegin(const C &c) -> decltype(c.begin())
Return const_iterator to the beginning of the container c.
Definition: stdFoam.H:190
const volScalarField & T
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant FixedList.
Definition: FixedListI.H:489
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:496
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:30
Bits that are independent of HashTable template parameters.
Definition: HashTableCore.H:54
#define WarningInFunction
Report a warning using Foam::Warning.
Hash function class. The default definition is for primitives. Non-primitives used to hash entries on...
Definition: Hash.H:47
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
void merge(HashTable< T, Key, Hash > &source)
Attempts to extract entries from source parameter and insert them into this, does not overwrite exist...
Definition: HashTable.C:895
surface1 clear()
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:163
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
Definition: HashTable.C:736
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
Definition: HashTable.C:801
triangles reserve(surf.size())
label filterKeys(const UnaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their keys.
void swap(HashTable< T, Key, Hash > &rhs) noexcept
Swap contents into this table.
Definition: HashTable.C:787
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant UList.
Definition: UListI.H:406
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant FixedList.
Definition: FixedListI.H:513
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:148
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
Foam::argList args(argc, argv)
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:168
List< label > toc(const UList< bool > &bools)
Return the (sorted) values corresponding to &#39;true&#39; entries.
Definition: BitOps.C:158
constexpr const_iterator cend() const noexcept
const_iterator to signal the end (for any HashTable)
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
void clearStorage()
Remove all entries from table and the table itself.
Definition: HashTable.C:774
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: UPtrList.H:366
List< Key > tocValues(const UnaryPredicate &pred, const bool invert=false) const
The table of contents (the keys) selected according to the unary predicate applied to the values...