29#ifndef Foam_HashTable_C
30#define Foam_HashTable_C
39template<
class T,
class Key,
class Hash>
49template<
class T,
class Key,
class Hash>
54 if (initialCapacity > 0)
59 std::fill_n(table_, capacity_,
static_cast<node_type*
>(
nullptr));
64template<
class T,
class Key,
class Hash>
71 insert(iter.key(), iter.val());
76template<
class T,
class Key,
class Hash>
81 capacity_(
rhs.capacity_),
91template<
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);
109template<
class T,
class Key,
class Hash>
112 const UList<Key>& keys,
113 const UList<T>& values,
117 HashTable<
T, Key, Hash>()
119 const label len = std::min(
keys.size(), values.size());
123 for (label i = 0; i < len; ++i)
125 this->setEntry(overwrite,
keys[i], values[i]);
132template<
class T,
class Key,
class Hash>
147template<
class T,
class Key,
class Hash>
155 list[count++] = iter.
key();
162template<
class T,
class Key,
class Hash>
165 List<Key> list(this->toc());
172template<
class T,
class Key,
class Hash>
173template<
class Compare>
186template<
class T,
class Key,
class Hash>
196 result.
set(count++, iter.
node());
205template<
class T,
class Key,
class Hash>
213 for (
iterator iter = begin(); iter != end(); ++iter)
215 result.
set(count++, iter.
node());
225template<
class T,
class Key,
class Hash>
226template<
class UnaryPredicate>
229 const UnaryPredicate& pred,
240 list[count++] = iter.
key();
251template<
class T,
class Key,
class Hash>
252template<
class UnaryPredicate>
255 const UnaryPredicate& pred,
266 list[count++] = iter.
key();
277template<
class T,
class Key,
class Hash>
278template<
class BinaryPredicate>
281 const BinaryPredicate& pred,
292 list[count++] = iter.
key();
303template<
class T,
class Key,
class Hash>
304template<
class UnaryPredicate>
307 const UnaryPredicate& pred,
325template<
class T,
class Key,
class Hash>
326template<
class UnaryPredicate>
329 const UnaryPredicate& pred,
347template<
class T,
class Key,
class Hash>
348template<
class BinaryPredicate>
351 const BinaryPredicate& pred,
369template<
class T,
class Key,
class Hash>
370template<
class... Args>
371bool Foam::HashTable<T, Key, Hash>::setEntry
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)...);
450template<
class T,
class Key,
class Hash>
451void Foam::HashTable<T, Key, Hash>::insert_node(node_type*
entry)
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_)
489 <<
"Not inserting " <<
entry->key() <<
": already in table\n"
495template<
class T,
class Key,
class Hash>
503 return iterator_erase(
const_cast<iterator&
>(iter));
507template<
class T,
class Key,
class Hash>
513 if (iter.good())
return iterator_erase(iter);
519template<
class T,
class Key,
class Hash>
520template<
class InputIter>
531 const label nTotal = this->size();
532 changed < nTotal && first != last;
536 if (this->
erase(*first))
546template<
class T,
class Key,
class Hash>
549 std::initializer_list<Key> keys
556template<
class T,
class Key,
class Hash>
567template<
class T,
class Key,
class Hash>
577template<
class T,
class Key,
class Hash>
578template<
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()))
610 changed < nTotal && iter !=
end();
625template<
class T,
class Key,
class Hash>
626template<
class AnyType,
class AnyHash>
632 const label nTotal = this->size();
645 for (iterator iter = begin(); iter != end(); ++iter)
658template<
class T,
class Key,
class Hash>
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;
728template<
class T,
class Key,
class Hash>
735template<
class T,
class Key,
class Hash>
738 if (numEntries > size_)
743 if (numEntries > capacity_)
setCapacity(numEntries);
748template<
class T,
class Key,
class Hash>
756 for (label i = 0, pending = size_; pending && i < capacity_; ++i)
773template<
class T,
class Key,
class Hash>
786template<
class T,
class Key,
class Hash>
794 std::swap(size_,
rhs.size_);
795 std::swap(capacity_,
rhs.capacity_);
796 std::swap(table_,
rhs.table_);
800template<
class T,
class Key,
class Hash>
813template<
class T,
class Key,
class Hash>
814template<
class UnaryPredicate>
817 const UnaryPredicate& pred,
823 for (
iterator iter = begin(); iter != end(); ++iter)
828 (pred(iter.key()) ? pruning : !pruning)
840template<
class T,
class Key,
class Hash>
841template<
class UnaryPredicate>
844 const UnaryPredicate& pred,
850 for (iterator iter =
begin(); iter !=
end(); ++iter)
855 (pred(iter.val()) ? pruning : !pruning)
867template<
class T,
class Key,
class Hash>
868template<
class BinaryPredicate>
871 const BinaryPredicate& pred,
877 for (
iterator iter = begin(); iter != end(); ++iter)
882 (pred(iter.key(), iter.val()) ? pruning : !pruning)
894template<
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);
918 if (emplace(iter.key()))
927template<
class T,
class Key,
class Hash>
936template<
class T,
class Key,
class Hash>
937void Foam::HashTable<T, Key, Hash>::operator=
952 insert(iter.key(), iter.val());
957template<
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);
973template<
class T,
class Key,
class Hash>
974void Foam::HashTable<T, Key, Hash>::operator=
983template<
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())
1009template<
class T,
class Key,
class Hash>
1012 const HashTable<T, Key, Hash>&
rhs
1019template<
class T,
class Key,
class Hash>
1026 if (
rhs.size() && (
this != &
rhs))
1032 insert(iter.key(), iter.val());
A 1D vector of objects of type <T> with a fixed length <N>.
bool good() const noexcept
True if iterator points to an entry.
const Key & key() const
The key associated with the iterator.
Forward iterator with const access.
reference val() const
Const access to referenced object (value).
Forward iterator with non-const access.
const node_type * node() const noexcept
Const access to the entry (node).
const_reference val() const
Const access to referenced object (value).
A HashTable similar to std::unordered_map.
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.
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.
const_iterator_pair< const_key_iterator, this_type > keys() const
A const iterator begin/end pair for iterating over keys.
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.
bool set(const Key &key, const T &obj)
Copy assign a new entry, overwriting existing entries.
Foam::label erase(InputIter first, InputIter last)
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.
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.
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...
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
void clearStorage()
Remove all entries from table and the table itself.
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.
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).
void resize(label newCapacity)
Rehash the hash table with new number of buckets. Currently identical to setCapacity().
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.
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
label countValues(const UnaryPredicate &pred, const bool invert=false) const
Count the number of values that satisfy the unary predicate.
label size() const noexcept
UPtrList< const node_type > csorted() const
Const access to the hash-table contents in sorted order (sorted by keys).
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
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...
bool emplace(const Key &key, Args &&... args)
Emplace insert a new entry, not overwriting existing entries.
void clear()
Remove all entries from table.
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).
constexpr HashTable() noexcept
Default construct: empty without allocation (capacity=0).
void resize(const label len)
Adjust allocated size of list.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
iterator begin() noexcept
Return an iterator to begin traversing the UList.
iterator end() noexcept
Return an iterator to end traversing the UList.
void size(const label n)
Older name for setAddressableSize.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
A keyword and a list of tokens is an 'entry'.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define WarningInFunction
Report a warning using Foam::Warning.
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
void sort(UList< T > &list)
Sort the list.
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
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.
errorManipArg< error, int > exit(error &err, const int errNo=1)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
constexpr char nl
The newline '\n' character (0x0a).
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...