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-2025 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>
50 Foam::HashTable<T, Key, Hash>::HashTable(const label initialCapacity)
51 :
52  HashTable<T, Key, Hash>()
53 {
54  if (initialCapacity > 0)
55  {
56  // Like resize() but no initial content to transfer
57  capacity_ = HashTableCore::canonicalSize(initialCapacity);
58  table_ = new node_type*[capacity_];
59  std::fill_n(table_, capacity_, static_cast<node_type*>(nullptr));
60  }
61 }
62 
63 
64 template<class T, class Key, class Hash>
65 Foam::HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
66 :
67  HashTable<T, Key, Hash>(2*ht.size())
68 {
69  for (const_iterator iter = ht.cbegin(); iter != ht.cend(); ++iter)
70  {
71  insert(iter.key(), iter.val());
72  }
73 }
74 
75 
76 template<class T, class Key, class Hash>
77 Foam::HashTable<T, Key, Hash>::HashTable(HashTable<T, Key, Hash>&& rhs) noexcept
78 :
79  HashTableCore(),
80  size_(rhs.size_),
81  capacity_(rhs.capacity_),
82  table_(rhs.table_)
83 {
84  // Stole all contents
85  rhs.size_ = 0;
86  rhs.capacity_ = 0;
87  rhs.table_ = nullptr;
88 }
89 
90 
91 template<class T, class Key, class Hash>
93 (
94  std::initializer_list<std::pair<Key, T>> list,
95  const bool overwrite
96 )
97 :
98  HashTable<T, Key, Hash>()
99 {
100  reserve(list.size());
101 
102  for (const auto& keyval : list)
103  {
104  this->setEntry(overwrite, keyval.first, keyval.second);
105  }
106 }
107 
108 
109 template<class T, class Key, class Hash>
111 (
112  const UList<Key>& keys,
113  const UList<T>& values,
114  const bool overwrite
115 )
116 :
117  HashTable<T, Key, Hash>()
118 {
119  const label len = std::min(keys.size(), values.size());
120 
121  reserve(len);
122 
123  for (label i = 0; i < len; ++i)
124  {
125  this->setEntry(overwrite, keys[i], values[i]);
126  }
127 }
128 
129 
130 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
131 
132 template<class T, class Key, class Hash>
134 {
135  // Remove all entries from table
136  clear();
137 
138  // Remove the table itself
139  capacity_ = 0;
140  delete[] table_;
141  table_ = nullptr;
142 }
143 
144 
145 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
146 
147 template<class T, class Key, class Hash>
149 {
150  List<Key> list(size_);
151  label count = 0;
152 
153  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
154  {
155  list[count++] = iter.key();
156  }
157 
158  return list;
159 }
160 
161 
162 template<class T, class Key, class Hash>
164 {
165  List<Key> list(this->toc());
166  Foam::sort(list);
167 
168  return list;
169 }
170 
171 
172 template<class T, class Key, class Hash>
173 template<class Compare>
175 (
176  const Compare& comp
177 ) const
178 {
179  List<Key> list(this->toc());
180  Foam::sort(list, comp);
182  return list;
183 }
184 
185 
186 template<class T, class Key, class Hash>
189 {
190  UPtrList<const node_type> result(size_);
191 
192  label count = 0;
193 
194  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
195  {
196  result.set(count++, iter.node());
197  }
198 
199  Foam::sort(result);
201  return result;
202 }
203 
204 
205 template<class T, class Key, class Hash>
208 {
209  UPtrList<node_type> result(size_);
210 
211  label count = 0;
212 
213  for (iterator iter = begin(); iter != end(); ++iter)
214  {
215  result.set(count++, iter.node());
216  }
217 
218  Foam::sort(result);
219 
220  return result;
221 }
222 
223 
224 
225 template<class T, class Key, class Hash>
226 template<class UnaryPredicate>
228 (
229  const UnaryPredicate& pred,
230  const bool invert
231 ) const
232 {
233  List<Key> list(size_);
234  label count = 0;
235 
236  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
237  {
238  if ((pred(iter.key()) ? !invert : invert))
239  {
240  list[count++] = iter.key();
241  }
242  }
243 
244  list.resize(count);
245  Foam::sort(list);
246 
247  return list;
248 }
249 
250 
251 template<class T, class Key, class Hash>
252 template<class UnaryPredicate>
254 (
255  const UnaryPredicate& pred,
256  const bool invert
257 ) const
258 {
259  List<Key> list(size_);
260  label count = 0;
261 
262  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
263  {
264  if ((pred(iter.val()) ? !invert : invert))
265  {
266  list[count++] = iter.key();
267  }
268  }
269 
270  list.resize(count);
271  Foam::sort(list);
272 
273  return list;
274 }
275 
276 
277 template<class T, class Key, class Hash>
278 template<class BinaryPredicate>
280 (
281  const BinaryPredicate& pred,
282  const bool invert
283 ) const
284 {
285  List<Key> list(size_);
286  label count = 0;
287 
288  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
289  {
290  if ((pred(iter.key(), iter.val()) ? !invert : invert))
291  {
292  list[count++] = iter.key();
293  }
294  }
295 
296  list.resize(count);
297  Foam::sort(list);
298 
299  return list;
300 }
301 
302 
303 template<class T, class Key, class Hash>
304 template<class UnaryPredicate>
306 (
307  const UnaryPredicate& pred,
308  const bool invert
309 ) const
310 {
311  label count = 0;
312 
313  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
314  {
315  if ((pred(iter.key()) ? !invert : invert))
316  {
317  ++count;
318  }
319  }
320 
321  return count;
322 }
323 
324 
325 template<class T, class Key, class Hash>
326 template<class UnaryPredicate>
328 (
329  const UnaryPredicate& pred,
330  const bool invert
331 ) const
332 {
333  label count = 0;
334 
335  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
336  {
337  if ((pred(iter.val()) ? !invert : invert))
338  {
339  ++count;
340  }
341  }
342 
343  return count;
344 }
345 
346 
347 template<class T, class Key, class Hash>
348 template<class BinaryPredicate>
350 (
351  const BinaryPredicate& pred,
352  const bool invert
353 ) const
354 {
355  label count = 0;
356 
357  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
358  {
359  if ((pred(iter.key(), iter.val()) ? !invert : invert))
360  {
361  ++count;
362  }
363  }
364 
365  return count;
366 }
367 
368 
369 template<class T, class Key, class Hash>
370 template<class... Args>
372 (
373  const bool overwrite,
374  const Key& key,
375  Args&&... args
376 )
377 {
378  if (!capacity_)
379  {
380  setCapacity(128); // Impose an initial capacity
381  }
382 
383  const label index = hashKeyIndex(key);
384 
385  node_type* curr = nullptr;
386  node_type* prev = nullptr;
387 
388  for (node_type* ep = table_[index]; ep; ep = ep->next_)
389  {
390  if (key == ep->key())
391  {
392  curr = ep;
393  break;
394  }
395  prev = ep;
396  }
397 
398  if (!curr)
399  {
400  // Not found, insert it at the head
401  table_[index] =
402  new node_type(table_[index], key, std::forward<Args>(args)...);
403 
404  ++size_;
405  if (0.8*capacity_ < size_) // Resize after 0.8 load factor
406  {
407  if (capacity_ < maxTableSize) setCapacity(2*capacity_);
408  }
409  }
410  else if (overwrite)
411  {
412  // Overwrite current entry (Perl convention).
413 
414  // Can skip if the value is not stored anyhow (Eg, HashSet)
415  // - this avoids a useless delete/new
416  if (!node_type::stores_value())
417  {
418  return true;
419  }
420 
421  node_type* ep = curr->next_; // next in the linked list
422 
423  // In some cases the delete/new could be avoided in favour of move
424  // assignment, but cannot be certain that all objects support this
425  // or that it behaves the same as a copy construct.
426 
427  delete curr;
428  ep = new node_type(ep, key, std::forward<Args>(args)...);
429 
430  // Replace current element - within list or insert at the head
431  if (prev)
432  {
433  prev->next_ = ep;
434  }
435  else
436  {
437  table_[index] = ep;
438  }
439  }
440  else
441  {
442  // Not overwriting existing entry
443  return false;
444  }
445 
446  return true;
447 }
448 
449 
450 template<class T, class Key, class Hash>
451 void Foam::HashTable<T, Key, Hash>::insert_node(node_type* entry)
452 {
453  if (!entry) return;
454 
455  if (!capacity_)
456  {
457  setCapacity(128); // Impose an initial capacity
458  }
459 
460  const label index = hashKeyIndex(entry->key());
461 
462  node_type* curr = nullptr;
463  //node_type* prev = nullptr;
464 
465  for (node_type* ep = table_[index]; ep; ep = ep->next_)
466  {
467  if (entry->key() == ep->key())
468  {
469  curr = ep;
470  break;
471  }
472  //prev = ep;
473  }
474 
475  if (!curr)
476  {
477  // Not found, insert it at the head
478  table_[index] = entry;
479 
480  ++size_;
481  if (0.8*capacity_ < size_) // Resize after 80% fill factor
482  {
483  if (capacity_ < maxTableSize) setCapacity(2*capacity_);
484  }
485  }
486  else
487  {
489  << "Not inserting " << entry->key() << ": already in table\n"
490  << exit(FatalError);
491  }
492 }
493 
494 
495 template<class T, class Key, class Hash>
496 bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter)
497 {
498  // NOTE: we use (const iterator&) here, but treat its contents as mutable.
499  //
500  // The parameter should be (iterator&), but then the compiler doesn't find
501  // it correctly and tries to call as (iterator) instead.
502 
503  return iterator_erase(const_cast<iterator&>(iter));
504 }
505 
506 
507 template<class T, class Key, class Hash>
509 {
510  if (size_)
511  {
512  iterator iter(find(key));
513  if (iter.good()) return iterator_erase(iter);
514  }
515  return false;
516 }
517 
518 
519 template<class T, class Key, class Hash>
520 template<class InputIter>
521 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
522 (
523  InputIter first,
524  InputIter last
525 )
526 {
527  label changed = 0;
528 
529  for
530  (
531  const label nTotal = this->size();
532  changed < nTotal && first != last; // terminate early
533  ++first
534  )
535  {
536  if (this->erase(*first))
537  {
538  ++changed;
539  }
540  }
542  return changed;
543 }
544 
545 
546 template<class T, class Key, class Hash>
547 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
548 (
549  std::initializer_list<Key> keys
550 )
551 {
552  return erase(keys.begin(), keys.end());
553 }
554 
555 
556 template<class T, class Key, class Hash>
557 template<unsigned N>
558 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
559 (
560  const FixedList<Key, N>& keys
561 )
562 {
563  return erase(keys.cbegin(), keys.cend());
564 }
565 
566 
567 template<class T, class Key, class Hash>
568 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
569 (
570  const UList<Key>& keys
571 )
572 {
573  return erase(keys.cbegin(), keys.cend());
574 }
575 
576 
577 template<class T, class Key, class Hash>
578 template<class AnyType, class AnyHash>
580 (
582 )
583 {
584  const label nTotal = this->size();
585  label changed = 0;
586 
587  if (other.size() <= nTotal)
588  {
589  // The other is smaller/same-size, use its keys for removal
590 
591  for
592  (
593  auto iter = other.cbegin();
594  changed < nTotal && iter != other.cend(); // Terminate early
595  ++iter
596  )
597  {
598  if (erase(iter.key()))
599  {
600  ++changed;
601  }
602  }
603  }
604  else
605  {
606  // We are smaller: remove if found in the other hash
607  for
608  (
609  iterator iter = begin();
610  changed < nTotal && iter != end(); // Terminate early
611  ++iter
612  )
613  {
614  if (other.contains(iter.key()) && erase(iter))
615  {
616  ++changed;
617  }
618  }
619  }
620 
621  return changed;
622 }
623 
624 
625 template<class T, class Key, class Hash>
626 template<class AnyType, class AnyHash>
628 (
630 )
631 {
632  const label nTotal = this->size();
633  label changed = 0;
634 
635  if (other.empty())
636  {
637  // Trivial case
638  changed = nTotal;
639  this->clear();
640  }
641  else
642  {
643  // Inverted logic: remove if *not* found in the other hash
644 
645  for (iterator iter = begin(); iter != end(); ++iter)
646  {
647  if (!other.contains(iter.key()) && erase(iter))
648  {
649  ++changed;
650  }
651  }
652  }
653 
654  return changed;
655 }
656 
657 
658 template<class T, class Key, class Hash>
659 void Foam::HashTable<T, Key, Hash>::setCapacity(label newCapacity)
660 {
661  newCapacity = HashTableCore::canonicalSize(newCapacity);
662 
663  if (newCapacity == capacity_)
664  {
665  return;
666  }
667 
668  if (!size_)
669  {
670  // Table is unpopulated - can already remove now
671  capacity_ = 0;
672  delete[] table_;
673  table_ = nullptr;
674  }
675 
676  if (!newCapacity)
677  {
678  // Special handling for capacity = 0.
679  if (size_)
680  {
682  << "HashTable contains " << size_
683  << " elements, cannot set capacity to 0 buckets!" << nl;
684  }
685  return;
686  }
687 
688  // Swap primary table entries: size_ is left untouched
689 
690  auto oldTable = table_;
691  const label oldCapacity = capacity_;
692 
693  capacity_ = newCapacity;
694  table_ = new node_type*[capacity_];
695  std::fill_n(table_, capacity_, static_cast<node_type*>(nullptr));
696 
697  if (!oldTable)
698  {
699  return;
700  }
701 
702  // Move to new table[] but with new chaining.
703 
704  for (label i = 0, pending = size_; pending && i < oldCapacity; ++i)
705  {
706  for (node_type* ep = oldTable[i]; ep; /*nil*/)
707  {
708  node_type* next = ep->next_;
709 
710  // Move to new location
711  {
712  const label newIdx = hashKeyIndex(ep->key());
713 
714  ep->next_ = table_[newIdx]; // add to head
715  table_[newIdx] = ep;
716  }
717 
718  ep = next; // continue in the linked-list
719  --pending; // note any early completion
720  }
721  oldTable[i] = nullptr;
722  }
723 
724  delete[] oldTable;
725 }
726 
727 
728 template<class T, class Key, class Hash>
730 {
731  setCapacity(newCapacity);
732 }
733 
734 
735 template<class T, class Key, class Hash>
736 void Foam::HashTable<T, Key, Hash>::reserve(label numEntries)
737 {
738  if (numEntries > size_)
739  {
740  // From number of entries to estimated capacity
741  // - initial load factor of 0.5
742  numEntries *= 2;
743  if (numEntries > capacity_) setCapacity(numEntries);
744  }
745 }
746 
747 
748 template<class T, class Key, class Hash>
750 {
751  if (!table_)
752  {
753  capacity_ = 0; // Paranoid
754  }
755 
756  for (label i = 0, pending = size_; pending && i < capacity_; ++i)
757  {
758  for (node_type* ep = table_[i]; ep; /*nil*/)
759  {
760  node_type* next = ep->next_;
761 
762  delete ep;
763 
764  ep = next; // continue in the linked-list
765  --pending; // note any early completion
766  }
767  table_[i] = nullptr;
768  }
769  size_ = 0;
770 }
771 
772 
773 template<class T, class Key, class Hash>
775 {
776  // Remove all entries from table
777  clear();
778 
779  // Remove the table itself
780  capacity_ = 0;
781  delete[] table_;
782  table_ = nullptr;
783 }
784 
785 
786 template<class T, class Key, class Hash>
788 {
789  if (this == &rhs)
790  {
791  return; // Self-swap is a no-op
792  }
793 
794  std::swap(size_, rhs.size_);
795  std::swap(capacity_, rhs.capacity_);
796  std::swap(table_, rhs.table_);
797 }
798 
799 
800 template<class T, class Key, class Hash>
802 {
803  if (this == &rhs)
804  {
805  return; // Self-assignment is a no-op
806  }
807 
808  clear();
809  swap(rhs);
810 }
811 
812 
813 template<class T, class Key, class Hash>
814 template<class UnaryPredicate>
816 (
817  const UnaryPredicate& pred,
818  const bool pruning
819 )
820 {
821  label changed = 0;
822 
823  for (iterator iter = begin(); iter != end(); ++iter)
824  {
825  // Matches? either prune (pruning) or keep (!pruning)
826  if
827  (
828  (pred(iter.key()) ? pruning : !pruning)
829  && erase(iter)
830  )
831  {
832  ++changed;
833  }
834  }
835 
836  return changed;
837 }
838 
839 
840 template<class T, class Key, class Hash>
841 template<class UnaryPredicate>
843 (
844  const UnaryPredicate& pred,
845  const bool pruning
846 )
847 {
848  label changed = 0;
849 
850  for (iterator iter = begin(); iter != end(); ++iter)
851  {
852  // Matches? either prune (pruning) or keep (!pruning)
853  if
854  (
855  (pred(iter.val()) ? pruning : !pruning)
856  && erase(iter)
857  )
858  {
859  ++changed;
860  }
861  }
862 
863  return changed;
864 }
865 
866 
867 template<class T, class Key, class Hash>
868 template<class BinaryPredicate>
870 (
871  const BinaryPredicate& pred,
872  const bool pruning
873 )
874 {
875  label changed = 0;
876 
877  for (iterator iter = begin(); iter != end(); ++iter)
878  {
879  // Matches? either prune (pruning) or keep (!pruning)
880  if
881  (
882  (pred(iter.key(), iter.val()) ? pruning : !pruning)
883  && erase(iter)
884  )
885  {
886  ++changed;
887  }
888  }
889 
890  return changed;
891 }
892 
893 
894 template<class T, class Key, class Hash>
895 void Foam::HashTable<T, Key, Hash>::merge(HashTable<T, Key, Hash>& source)
896 {
897  // Self-merge implicitly a no-op
898 
899  if (node_type::stores_value())
900  {
901  // key/val pair
902  for (iterator iter = source.begin(); iter != source.end(); ++iter)
903  {
904  if (!contains(iter.key()))
905  {
906  node_type* entry = source.iterator_extract(iter);
907  this->insert_node(entry);
908  }
909  }
910  }
911  else
912  {
913  // key only, does not store a value.
914  // Since the key is const, juggling the node does not work
915 
916  for (iterator iter = source.begin(); iter != source.end(); ++iter)
917  {
918  if (emplace(iter.key()))
919  {
920  source.erase(iter);
921  }
922  }
923  }
924 }
925 
926 
927 template<class T, class Key, class Hash>
928 void Foam::HashTable<T, Key, Hash>::merge(HashTable<T, Key, Hash>&& source)
929 {
930  merge(source);
931 }
932 
933 
934 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
935 
936 template<class T, class Key, class Hash>
938 (
939  const HashTable<T, Key, Hash>& rhs
940 )
941 {
942  if (this == &rhs)
943  {
944  return; // Self-assignment is a no-op
945  }
946 
947  this->clear();
948  this->reserve(rhs.size());
949 
950  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
951  {
952  insert(iter.key(), iter.val());
953  }
954 }
955 
956 
957 template<class T, class Key, class Hash>
959 (
960  std::initializer_list<std::pair<Key, T>> rhs
961 )
962 {
963  this->clear();
964  this->reserve(rhs.size());
965 
966  for (const auto& keyval : rhs)
967  {
968  set(keyval.first, keyval.second);
969  }
970 }
971 
972 
973 template<class T, class Key, class Hash>
975 (
976  HashTable<T, Key, Hash>&& rhs
977 )
978 {
979  transfer(rhs); // Includes self-assignment check
980 }
981 
982 
983 template<class T, class Key, class Hash>
985 (
986  const HashTable<T, Key, Hash>& rhs
987 ) const
988 {
989  // Sizes (number of keys) must match
990  if (size() != rhs.size())
991  {
992  return false;
993  }
994 
995  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
996  {
997  const const_iterator other(this->cfind(iter.key()));
998 
999  if (!other.good() || other.val() != iter.val())
1000  {
1001  return false;
1002  }
1003  }
1005  return true;
1006 }
1007 
1008 
1009 template<class T, class Key, class Hash>
1011 (
1012  const HashTable<T, Key, Hash>& rhs
1013 ) const
1015  return !operator==(rhs);
1016 }
1017 
1018 
1019 template<class T, class Key, class Hash>
1021 (
1022  const HashTable<T, Key, Hash>& rhs
1023 )
1024 {
1025  // Avoid no-ops:
1026  if (rhs.size() && (this != &rhs))
1027  {
1028  if (this->size())
1029  {
1030  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
1031  {
1032  insert(iter.key(), iter.val());
1033  }
1034  }
1035  else
1036  {
1037  (*this) = rhs;
1038  }
1039  }
1040 
1041  return *this;
1042 }
1043 
1044 
1045 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1046 
1047 // Iterators, Friend Operators
1048 
1049 #include "HashTableIter.C"
1050 #include "HashTableIO.C"
1051 
1052 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1053 
1054 #endif
1055 
1056 // ************************************************************************* //
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:840
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:443
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:150
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:600
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:181
void setCapacity(label newCapacity)
Change the hash table capacity (number of buckets).
Definition: HashTable.C:652
UPtrList< node_type > sorted()
Non-const access to the hash-table contents in sorted order (sorted by keys).
Definition: HashTable.C:200
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:126
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:295
void clear()
Remove all entries from table.
Definition: HashTable.C:742
auto key(const Type &t) -> std::enable_if_t< std::is_enum_v< Type >, std::underlying_type_t< Type > >
Definition: foamGltfBase.H:103
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:722
const direction noexcept
Definition: scalarImpl.H:255
bool empty() const noexcept
True if the hash table is empty.
Definition: HashTable.H:353
const volScalarField & T
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant FixedList.
Definition: FixedListI.H:489
constexpr HashTable() noexcept
Default construct: empty without allocation (capacity=0)
Definition: HashTable.C:33
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:489
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:28
Bits that are independent of HashTable template parameters.
Definition: HashTableCore.H:53
#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
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:888
surface1 clear()
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:156
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
Definition: HashTable.C:729
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
Definition: HashTable.C:794
const char * end
Definition: SVGTools.H:223
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:780
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant UList.
Definition: UListI.H:399
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant FixedList.
Definition: FixedListI.H:537
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:141
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)
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:767
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...