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