29 #ifndef Foam_HashTable_C 30 #define Foam_HashTable_C 39 template<
class T,
class Key,
class Hash>
49 template<
class T,
class Key,
class Hash>
54 if (initialCapacity > 0)
57 capacity_ = HashTableCore::canonicalSize(initialCapacity);
58 table_ =
new node_type*[capacity_];
59 std::fill_n(table_, capacity_, static_cast<node_type*>(
nullptr));
64 template<
class T,
class Key,
class Hash>
67 HashTable<
T, Key, Hash>(2*ht.size())
69 for (const_iterator iter = ht.cbegin(); iter != ht.cend(); ++iter)
71 insert(iter.key(), iter.val());
76 template<
class T,
class Key,
class Hash>
81 capacity_(rhs.capacity_),
91 template<
class T,
class Key,
class Hash>
94 std::initializer_list<std::pair<Key, T>> list,
102 for (
const auto& keyval : list)
104 this->setEntry(overwrite, keyval.first, keyval.second);
109 template<
class T,
class Key,
class Hash>
112 const UList<Key>& keys,
117 HashTable<
T, Key, Hash>()
123 for (label i = 0; i < len; ++i)
125 this->setEntry(overwrite, keys[i],
values[i]);
132 template<
class T,
class Key,
class Hash>
147 template<
class T,
class Key,
class Hash>
153 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
155 list[
count++] = iter.key();
162 template<
class T,
class Key,
class Hash>
165 List<Key> list(this->
toc());
172 template<
class T,
class Key,
class Hash>
173 template<
class Compare>
186 template<
class T,
class Key,
class Hash>
194 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
205 template<
class T,
class Key,
class Hash>
213 for (iterator iter = begin(); iter !=
end(); ++iter)
225 template<
class T,
class Key,
class Hash>
226 template<
class UnaryPredicate>
229 const UnaryPredicate& pred,
236 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
240 list[
count++] = iter.key();
251 template<
class T,
class Key,
class Hash>
252 template<
class UnaryPredicate>
255 const UnaryPredicate& pred,
262 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
266 list[
count++] = iter.key();
277 template<
class T,
class Key,
class Hash>
278 template<
class BinaryPredicate>
281 const BinaryPredicate& pred,
288 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
292 list[
count++] = iter.key();
303 template<
class T,
class Key,
class Hash>
304 template<
class UnaryPredicate>
307 const UnaryPredicate& pred,
313 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
325 template<
class T,
class Key,
class Hash>
326 template<
class UnaryPredicate>
329 const UnaryPredicate& pred,
335 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
347 template<
class T,
class Key,
class Hash>
348 template<
class BinaryPredicate>
351 const BinaryPredicate& pred,
357 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
369 template<
class T,
class Key,
class Hash>
370 template<
class... Args>
373 const bool overwrite,
383 const label index = hashKeyIndex(
key);
385 node_type* curr =
nullptr;
386 node_type* prev =
nullptr;
388 for (node_type* ep = table_[index]; ep; ep = ep->next_)
390 if (
key == ep->key())
402 new node_type(table_[index],
key, std::forward<Args>(
args)...);
405 if (0.8*capacity_ < size_)
407 if (capacity_ < maxTableSize) setCapacity(2*capacity_);
416 if (!node_type::stores_value())
421 node_type* ep = curr->next_;
428 ep =
new node_type(ep,
key, std::forward<Args>(
args)...);
450 template<
class T,
class Key,
class Hash>
460 const label index = hashKeyIndex(entry->key());
462 node_type* curr =
nullptr;
465 for (node_type* ep = table_[index]; ep; ep = ep->next_)
467 if (entry->key() == ep->key())
478 table_[index] = entry;
481 if (0.8*capacity_ < size_)
483 if (capacity_ < maxTableSize) setCapacity(2*capacity_);
489 <<
"Not inserting " <<
entry->key() <<
": already in table\n" 495 template<
class T,
class Key,
class Hash>
503 return iterator_erase(const_cast<iterator&>(iter));
507 template<
class T,
class Key,
class Hash>
513 if (iter.good())
return iterator_erase(iter);
519 template<
class T,
class Key,
class Hash>
520 template<
class InputIter>
531 const label nTotal = this->size();
532 changed < nTotal && first != last;
536 if (this->
erase(*first))
546 template<
class T,
class Key,
class Hash>
549 std::initializer_list<Key> keys
552 return erase(keys.begin(), keys.end());
556 template<
class T,
class Key,
class Hash>
567 template<
class T,
class Key,
class Hash>
577 template<
class T,
class Key,
class Hash>
578 template<
class AnyType,
class AnyHash>
584 const label nTotal = this->size();
587 if (other.
size() <= nTotal)
593 auto iter = other.
cbegin();
594 changed < nTotal && iter != other.
cend();
598 if (
erase(iter.key()))
609 iterator iter = begin();
610 changed < nTotal && iter !=
end();
625 template<
class T,
class Key,
class Hash>
626 template<
class AnyType,
class AnyHash>
632 const label nTotal = this->size();
645 for (iterator iter = begin(); iter !=
end(); ++iter)
658 template<
class T,
class Key,
class Hash>
661 newCapacity = HashTableCore::canonicalSize(newCapacity);
663 if (newCapacity == capacity_)
682 <<
"HashTable contains " << size_
683 <<
" elements, cannot set capacity to 0 buckets!" <<
nl;
690 auto oldTable = table_;
691 const label oldCapacity = capacity_;
693 capacity_ = newCapacity;
694 table_ =
new node_type*[capacity_];
695 std::fill_n(table_, capacity_, static_cast<node_type*>(
nullptr));
704 for (label i = 0, pending = size_; pending && i < oldCapacity; ++i)
706 for (node_type* ep = oldTable[i]; ep; )
708 node_type* next = ep->next_;
712 const label newIdx = hashKeyIndex(ep->key());
714 ep->next_ = table_[newIdx];
721 oldTable[i] =
nullptr;
728 template<
class T,
class Key,
class Hash>
731 setCapacity(newCapacity);
735 template<
class T,
class Key,
class Hash>
738 if (numEntries > size_)
743 if (numEntries > capacity_) setCapacity(numEntries);
748 template<
class T,
class Key,
class Hash>
756 for (label i = 0, pending = size_; pending && i < capacity_; ++i)
758 for (node_type* ep = table_[i]; ep; )
760 node_type* next = ep->next_;
773 template<
class T,
class Key,
class Hash>
786 template<
class T,
class Key,
class Hash>
794 std::swap(size_, rhs.size_);
795 std::swap(capacity_, rhs.capacity_);
796 std::swap(table_, rhs.table_);
800 template<
class T,
class Key,
class Hash>
813 template<
class T,
class Key,
class Hash>
814 template<
class UnaryPredicate>
817 const UnaryPredicate& pred,
823 for (iterator iter = begin(); iter !=
end(); ++iter)
828 (pred(iter.key()) ? pruning : !pruning)
840 template<
class T,
class Key,
class Hash>
841 template<
class UnaryPredicate>
844 const UnaryPredicate& pred,
850 for (iterator iter = begin(); iter !=
end(); ++iter)
855 (pred(iter.val()) ? pruning : !pruning)
867 template<
class T,
class Key,
class Hash>
868 template<
class BinaryPredicate>
871 const BinaryPredicate& pred,
877 for (iterator iter = begin(); iter !=
end(); ++iter)
882 (pred(iter.key(), iter.val()) ? pruning : !pruning)
894 template<
class T,
class Key,
class Hash>
899 if (node_type::stores_value())
902 for (iterator iter = source.begin(); iter != source.end(); ++iter)
904 if (!contains(iter.key()))
906 node_type* entry = source.iterator_extract(iter);
907 this->insert_node(entry);
916 for (iterator iter = source.begin(); iter != source.end(); ++iter)
918 if (emplace(iter.key()))
927 template<
class T,
class Key,
class Hash>
936 template<
class T,
class Key,
class Hash>
939 const HashTable<T, Key, Hash>& rhs
950 for (const_iterator iter = rhs.
cbegin(); iter != rhs.
cend(); ++iter)
957 template<
class T,
class Key,
class Hash>
960 std::initializer_list<std::pair<Key, T>> rhs
966 for (
const auto& keyval : rhs)
968 set(keyval.first, keyval.second);
973 template<
class T,
class Key,
class Hash>
976 HashTable<T, Key, Hash>&& rhs
983 template<
class T,
class Key,
class Hash>
990 if (size() != rhs.
size())
995 for (const_iterator iter = rhs.
cbegin(); iter != rhs.
cend(); ++iter)
997 const const_iterator other(this->cfind(iter.key()));
999 if (!other.good() || other.val() != iter.val())
1009 template<
class T,
class Key,
class Hash>
1019 template<
class T,
class Key,
class Hash>
1026 if (rhs.
size() && (
this != &rhs))
1030 for (const_iterator iter = rhs.
cbegin(); iter != rhs.
cend(); ++iter)
1032 insert(iter.key(), iter.val());
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.
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.
errorManipArg< error, int > exit(error &err, const int errNo=1)
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>.
void resize(const label len)
Adjust allocated size of list.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
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...
srcOptions insert("case", fileName(rootDirSource/caseDirSource))
constexpr char nl
The newline '\n' character (0x0a)
UPtrList< const node_type > csorted() const
Const access to the hash-table contents in sorted order (sorted by keys).
void setCapacity(label newCapacity)
Change the hash table capacity (number of buckets).
UPtrList< node_type > sorted()
Non-const access to the hash-table contents in sorted order (sorted by keys).
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< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
label size() const noexcept
The number of elements in table.
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 'true' entries.
bool contains(const Key &key) const
True if hashed key is contained (found) in table.
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.
void clear()
Remove all entries from table.
auto key(const Type &t) -> std::enable_if_t< std::is_enum_v< Type >, std::underlying_type_t< Type > >
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.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
void resize(label newCapacity)
Rehash the hash table with new number of buckets. Currently identical to setCapacity() ...
bool empty() const noexcept
True if the hash table is empty.
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant FixedList.
constexpr HashTable() noexcept
Default construct: empty without allocation (capacity=0)
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Bits that are independent of HashTable template parameters.
#define WarningInFunction
Report a warning using Foam::Warning.
Hash function class. The default definition is for primitives. Non-primitives used to hash entries on...
void merge(HashTable< T, Key, Hash > &source)
Attempts to extract entries from source parameter and insert them into this, does not overwrite exist...
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
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.
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant UList.
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant FixedList.
List< Key > toc() const
The table of contents (the keys) in unsorted order.
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 'true' entries.
constexpr const_iterator cend() const noexcept
const_iterator to signal the end (for any HashTable)
A keyword and a list of tokens is an 'entry'.
void clearStorage()
Remove all entries from table and the table itself.
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
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...