Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
11License
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.
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
39template<class T, class Key, class Hash>
41:
43 size_(0),
44 capacity_(0),
45 table_(nullptr)
46{}
47
48
49template<class T, class Key, class Hash>
50Foam::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
64template<class T, class Key, class Hash>
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
76template<class T, class Key, class Hash>
78:
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
91template<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)
104 this->setEntry(overwrite, keyval.first, keyval.second);
105 }
106}
107
108
109template<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]);
127}
128
129
130// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
131
132template<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
147template<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();
157
158 return list;
159}
160
161
162template<class T, class Key, class Hash>
164{
165 List<Key> list(this->toc());
166 Foam::sort(list);
168 return list;
169}
170
171
172template<class T, class Key, class Hash>
173template<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
186template<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
205template<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
225template<class T, class Key, class Hash>
226template<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);
247 return list;
248}
249
250
251template<class T, class Key, class Hash>
252template<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);
273 return list;
274}
275
276
277template<class T, class Key, class Hash>
278template<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)
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);
299 return list;
300}
301
302
303template<class T, class Key, class Hash>
304template<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 }
321 return count;
322}
323
324
325template<class T, class Key, class Hash>
326template<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 }
343 return count;
344}
345
346
347template<class T, class Key, class Hash>
348template<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
369template<class T, class Key, class Hash>
370template<class... Args>
371bool Foam::HashTable<T, Key, Hash>::setEntry
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
450template<class T, class Key, class Hash>
451void 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);
492}
493
494
495template<class T, class Key, class Hash>
496bool 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
507template<class T, class Key, class Hash>
508bool Foam::HashTable<T, Key, Hash>::erase(const Key& key)
509{
510 if (size_)
511 {
512 iterator iter(find(key));
513 if (iter.good()) return iterator_erase(iter);
515 return false;
516}
517
518
519template<class T, class Key, class Hash>
520template<class InputIter>
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 }
541
542 return changed;
543}
544
545
546template<class T, class Key, class Hash>
548(
549 std::initializer_list<Key> keys
550)
552 return erase(keys.begin(), keys.end());
553}
554
555
556template<class T, class Key, class Hash>
557template<unsigned N>
559(
560 const FixedList<Key, N>& keys
562{
563 return erase(keys.cbegin(), keys.cend());
564}
565
566
567template<class T, class Key, class Hash>
569(
570 const UList<Key>& keys
571)
573 return erase(keys.cbegin(), keys.cend());
574}
575
576
577template<class T, class Key, class Hash>
578template<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 }
621 return changed;
622}
623
624
625template<class T, class Key, class Hash>
626template<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 }
653
654 return changed;
655}
656
657
658template<class T, class Key, class Hash>
659void 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;
723
724 delete[] oldTable;
726
727
728template<class T, class Key, class Hash>
730{
731 setCapacity(newCapacity);
733
734
735template<class T, class Key, class Hash>
736void 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}
747
748template<class T, class Key, class Hash>
750{
751 if (!table_)
753 capacity_ = 0; // Paranoid
754 }
755
756 for (label i = 0, pending = size_; pending && i < capacity_; ++i)
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
773template<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
786template<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
800template<class T, class Key, class Hash>
802{
803 if (this == &rhs)
804 {
805 return; // Self-assignment is a no-op
806 }
807
809 swap(rhs);
810}
811
812
813template<class T, class Key, class Hash>
814template<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 }
836 return changed;
837}
838
840template<class T, class Key, class Hash>
841template<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 }
863 return changed;
864}
865
866
867template<class T, class Key, class Hash>
868template<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 }
889
890 return changed;
891}
892
893
894template<class T, class Key, class Hash>
895void 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);
922 }
923 }
924}
925
926
927template<class T, class Key, class Hash>
929{
930 merge(source);
931}
932
933
934// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
935
936template<class T, class Key, class Hash>
937void Foam::HashTable<T, Key, Hash>::operator=
938(
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)
952 insert(iter.key(), iter.val());
953 }
954}
955
956
957template<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
973template<class T, class Key, class Hash>
974void Foam::HashTable<T, Key, Hash>::operator=
975(
978{
979 transfer(rhs); // Includes self-assignment check
980}
981
982
983template<class T, class Key, class Hash>
985(
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 }
1004
1005 return true;
1006}
1007
1008
1009template<class T, class Key, class Hash>
1011(
1012 const HashTable<T, Key, Hash>& rhs
1013) const
1014{
1015 return !operator==(rhs);
1016}
1017
1018
1019template<class T, class Key, class Hash>
1021(
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// ************************************************************************* //
A 1D vector of objects of type <T> with a fixed length <N>.
Definition FixedList.H:73
bool good() const noexcept
True if iterator points to an entry.
Definition HashTable.H:990
const Key & key() const
The key associated with the iterator.
Definition HashTable.H:1000
Forward iterator with const access.
Definition HashTable.H:1135
reference val() const
Const access to referenced object (value).
Definition HashTable.H:1201
Forward iterator with non-const access.
Definition HashTable.H:1043
const node_type * node() const noexcept
Const access to the entry (node).
Definition HashTable.H:1081
const_reference val() const
Const access to referenced object (value).
Definition HashTable.H:1097
A HashTable similar to std::unordered_map.
Definition HashTable.H:124
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...
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition HashTable.C:156
label countEntries(const BinaryPredicate &pred, const bool invert=false) const
Count the number of entries that satisfy the binary predicate.
void swap(HashTable< T, Key, Hash > &rhs) noexcept
Swap contents into this table.
Definition HashTable.C:780
const_iterator_pair< const_key_iterator, this_type > keys() const
A const iterator begin/end pair for iterating over keys.
Definition HashTable.H:1295
label countKeys(const UnaryPredicate &pred, const bool invert=false) const
Count the number of keys that satisfy the unary predicate.
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition HashTable.C:141
bool set(const Key &key, const T &obj)
Copy assign a new entry, overwriting existing entries.
Definition HashTableI.H:174
Foam::label erase(InputIter first, InputIter last)
Definition HashTable.C:515
label retain(const HashTable< AnyType, Key, AnyHash > &other)
Retain table entries given by keys of the other hash-table.
bool empty() const noexcept
True if the hash table is empty.
Definition HashTable.H:353
iterator begin()
iterator set to the beginning of the HashTable
bool contains(const Key &key) const
True if hashed key is contained (found) in table.
Definition HashTableI.H:72
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
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
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition HashTableI.H:113
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 clearStorage()
Remove all entries from table and the table itself.
Definition HashTable.C:767
label filterValues(const UnaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their values.
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.
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
Definition HashTable.C:794
label filterEntries(const BinaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their key/value.
UPtrList< node_type > sorted()
Non-const access to the hash-table contents in sorted order (sorted by keys).
Definition HashTable.C:200
void resize(label newCapacity)
Rehash the hash table with new number of buckets. Currently identical to setCapacity().
Definition HashTable.C:722
friend Ostream & operator(Ostream &, const HashTable< T, Key, Hash > &tbl)
label filterKeys(const UnaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their keys.
~HashTable()
Destructor.
Definition HashTable.C:126
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
Definition HashTableI.H:86
label countValues(const UnaryPredicate &pred, const bool invert=false) const
Count the number of values that satisfy the unary predicate.
label size() const noexcept
Definition HashTable.H:358
UPtrList< const node_type > csorted() const
Const access to the hash-table contents in sorted order (sorted by keys).
Definition HashTable.C:181
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition HashTable.C:489
std::conditional_t< std::is_same_v< Foam::zero, std::remove_cv_t< T > >, Detail::HashTableSingle< Key >, Detail::HashTablePair< Key, T > > node_type
A table entry (node) that encapsulates the key/val tuple with an additional linked-list entry for has...
Definition HashTable.H:138
bool emplace(const Key &key, Args &&... args)
Emplace insert a new entry, not overwriting existing entries.
Definition HashTableI.H:129
void clear()
Remove all entries from table.
Definition HashTable.C:742
iterator end() noexcept
iterator to signal the end (for any HashTable)
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.
constexpr const_iterator cend() const noexcept
const_iterator to signal the end (for any HashTable)
void setCapacity(label newCapacity)
Change the hash table capacity (number of buckets).
Definition HashTable.C:652
constexpr HashTable() noexcept
Default construct: empty without allocation (capacity=0).
Definition HashTable.C:33
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition UListI.H:454
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition UPtrList.H:101
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
A keyword and a list of tokens is an 'entry'.
Definition entry.H:66
const volScalarField & T
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
surface1 clear()
#define WarningInFunction
Report a warning using Foam::Warning.
const char * end
Definition SVGTools.H:223
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
void sort(UList< T > &list)
Sort the list.
Definition UList.C:283
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition ListOps.C:28
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
srcOptions erase("case")
triangles reserve(surf.size())
Foam::argList args(argc, argv)
nonInt insert("surfaceSum(((S|magSf)*S)")
Bits that are independent of HashTable template parameters.
static constexpr int32_t maxTableSize
Maximum allowable internal table size (must be a power of two!).
constexpr HashTableCore() noexcept=default
Default construct.
static label canonicalSize(const label size) noexcept
Return a canonical (power-of-two) of the requested size.
Hash function class. The default definition is for primitives. Non-primitives used to hash entries on...
Definition Hash.H:48