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>
56 template<
class T,
class Key,
class Hash>
61 if (initialCapacity > 0)
64 capacity_ = HashTableCore::canonicalSize(initialCapacity);
65 table_ =
new node_type*[capacity_];
66 std::fill_n(table_, capacity_, static_cast<node_type*>(
nullptr));
71 template<
class T,
class Key,
class Hash>
74 HashTable<
T, Key, Hash>(2*ht.size())
76 for (const_iterator iter = ht.cbegin(); iter != ht.cend(); ++iter)
78 insert(iter.key(), iter.val());
83 template<
class T,
class Key,
class Hash>
88 capacity_(rhs.capacity_),
98 template<
class T,
class Key,
class Hash>
101 std::initializer_list<std::pair<Key, T>> list,
109 for (
const auto& keyval : list)
111 this->setEntry(overwrite, keyval.first, keyval.second);
116 template<
class T,
class Key,
class Hash>
119 const UList<Key>& keys,
124 HashTable<
T, Key, Hash>()
130 for (label i = 0; i < len; ++i)
132 this->setEntry(overwrite, keys[i],
values[i]);
139 template<
class T,
class Key,
class Hash>
154 template<
class T,
class Key,
class Hash>
160 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
162 list[
count++] = iter.key();
169 template<
class T,
class Key,
class Hash>
172 List<Key> list(this->
toc());
179 template<
class T,
class Key,
class Hash>
180 template<
class Compare>
193 template<
class T,
class Key,
class Hash>
201 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
212 template<
class T,
class Key,
class Hash>
220 for (iterator iter =
begin(); iter !=
end(); ++iter)
232 template<
class T,
class Key,
class Hash>
233 template<
class UnaryPredicate>
236 const UnaryPredicate& pred,
243 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
247 list[
count++] = iter.key();
258 template<
class T,
class Key,
class Hash>
259 template<
class UnaryPredicate>
262 const UnaryPredicate& pred,
269 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
273 list[
count++] = iter.key();
284 template<
class T,
class Key,
class Hash>
285 template<
class BinaryPredicate>
288 const BinaryPredicate& pred,
295 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
299 list[
count++] = iter.key();
310 template<
class T,
class Key,
class Hash>
311 template<
class UnaryPredicate>
314 const UnaryPredicate& pred,
320 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
332 template<
class T,
class Key,
class Hash>
333 template<
class UnaryPredicate>
336 const UnaryPredicate& pred,
342 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
354 template<
class T,
class Key,
class Hash>
355 template<
class BinaryPredicate>
358 const BinaryPredicate& pred,
364 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
376 template<
class T,
class Key,
class Hash>
377 template<
class... Args>
380 const bool overwrite,
390 const label index = hashKeyIndex(
key);
392 node_type* curr =
nullptr;
393 node_type* prev =
nullptr;
395 for (node_type* ep = table_[index]; ep; ep = ep->next_)
397 if (
key == ep->key())
409 new node_type(table_[index],
key, std::forward<Args>(
args)...);
412 if (0.8*capacity_ < size_)
414 if (capacity_ < maxTableSize) setCapacity(2*capacity_);
423 if (!node_type::stores_value())
428 node_type* ep = curr->next_;
435 ep =
new node_type(ep,
key, std::forward<Args>(
args)...);
457 template<
class T,
class Key,
class Hash>
467 const label index = hashKeyIndex(entry->key());
469 node_type* curr =
nullptr;
472 for (node_type* ep = table_[index]; ep; ep = ep->next_)
474 if (entry->key() == ep->key())
485 table_[index] = entry;
488 if (0.8*capacity_ < size_)
490 if (capacity_ < maxTableSize) setCapacity(2*capacity_);
496 <<
"Not inserting " <<
entry->key() <<
": already in table\n" 502 template<
class T,
class Key,
class Hash>
510 return iterator_erase(const_cast<iterator&>(iter));
514 template<
class T,
class Key,
class Hash>
520 if (iter.good())
return iterator_erase(iter);
526 template<
class T,
class Key,
class Hash>
527 template<
class InputIter>
538 const label nTotal = this->size();
539 changed < nTotal && first != last;
543 if (this->
erase(*first))
553 template<
class T,
class Key,
class Hash>
556 std::initializer_list<Key> keys
559 return erase(keys.begin(), keys.end());
563 template<
class T,
class Key,
class Hash>
574 template<
class T,
class Key,
class Hash>
584 template<
class T,
class Key,
class Hash>
585 template<
class AnyType,
class AnyHash>
591 const label nTotal = this->size();
594 if (other.
size() <= nTotal)
600 auto iter = other.
cbegin();
601 changed < nTotal && iter != other.
cend();
605 if (
erase(iter.key()))
616 iterator iter =
begin();
617 changed < nTotal && iter !=
end();
632 template<
class T,
class Key,
class Hash>
633 template<
class AnyType,
class AnyHash>
639 const label nTotal = this->size();
652 for (iterator iter =
begin(); iter !=
end(); ++iter)
665 template<
class T,
class Key,
class Hash>
668 newCapacity = HashTableCore::canonicalSize(newCapacity);
670 if (newCapacity == capacity_)
689 <<
"HashTable contains " << size_
690 <<
" elements, cannot set capacity to 0 buckets!" <<
nl;
697 auto oldTable = table_;
698 const label oldCapacity = capacity_;
700 capacity_ = newCapacity;
701 table_ =
new node_type*[capacity_];
702 std::fill_n(table_, capacity_, static_cast<node_type*>(
nullptr));
711 for (label i = 0, pending = size_; pending && i < oldCapacity; ++i)
713 for (node_type* ep = oldTable[i]; ep; )
715 node_type* next = ep->next_;
719 const label newIdx = hashKeyIndex(ep->key());
721 ep->next_ = table_[newIdx];
728 oldTable[i] =
nullptr;
735 template<
class T,
class Key,
class Hash>
738 setCapacity(newCapacity);
742 template<
class T,
class Key,
class Hash>
745 if (numEntries > size_)
750 if (numEntries > capacity_) setCapacity(numEntries);
755 template<
class T,
class Key,
class Hash>
763 for (label i = 0, pending = size_; pending && i < capacity_; ++i)
765 for (node_type* ep = table_[i]; ep; )
767 node_type* next = ep->next_;
780 template<
class T,
class Key,
class Hash>
793 template<
class T,
class Key,
class Hash>
801 std::swap(size_, rhs.size_);
802 std::swap(capacity_, rhs.capacity_);
803 std::swap(table_, rhs.table_);
807 template<
class T,
class Key,
class Hash>
820 template<
class T,
class Key,
class Hash>
821 template<
class UnaryPredicate>
824 const UnaryPredicate& pred,
830 for (iterator iter =
begin(); iter !=
end(); ++iter)
835 (pred(iter.key()) ? pruning : !pruning)
847 template<
class T,
class Key,
class Hash>
848 template<
class UnaryPredicate>
851 const UnaryPredicate& pred,
857 for (iterator iter =
begin(); iter !=
end(); ++iter)
862 (pred(iter.val()) ? pruning : !pruning)
874 template<
class T,
class Key,
class Hash>
875 template<
class BinaryPredicate>
878 const BinaryPredicate& pred,
884 for (iterator iter =
begin(); iter !=
end(); ++iter)
889 (pred(iter.key(), iter.val()) ? pruning : !pruning)
901 template<
class T,
class Key,
class Hash>
906 if (node_type::stores_value())
909 for (iterator iter = source.begin(); iter != source.end(); ++iter)
911 if (!contains(iter.key()))
913 node_type* entry = source.iterator_extract(iter);
914 this->insert_node(entry);
923 for (iterator iter = source.begin(); iter != source.end(); ++iter)
925 if (emplace(iter.key()))
934 template<
class T,
class Key,
class Hash>
943 template<
class T,
class Key,
class Hash>
946 const HashTable<T, Key, Hash>& rhs
957 for (const_iterator iter = rhs.
cbegin(); iter != rhs.
cend(); ++iter)
964 template<
class T,
class Key,
class Hash>
967 std::initializer_list<std::pair<Key, T>> rhs
973 for (
const auto& keyval : rhs)
975 set(keyval.first, keyval.second);
980 template<
class T,
class Key,
class Hash>
983 HashTable<T, Key, Hash>&& rhs
990 template<
class T,
class Key,
class Hash>
997 if (size() != rhs.
size())
1002 for (const_iterator iter = rhs.
cbegin(); iter != rhs.
cend(); ++iter)
1004 const const_iterator other(this->cfind(iter.key()));
1006 if (!other.good() || other.val() != iter.val())
1016 template<
class T,
class Key,
class Hash>
1026 template<
class T,
class Key,
class Hash>
1033 if (rhs.
size() && (
this != &rhs))
1037 for (const_iterator iter = rhs.
cbegin(); iter != rhs.
cend(); ++iter)
1039 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).
HashTable() noexcept
Default construct: empty without allocation (capacity=0)
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.
constexpr auto cend(const C &c) -> decltype(c.end())
Return const_iterator to the end of the container c.
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.
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
constexpr auto cbegin(const C &c) -> decltype(c.begin())
Return const_iterator to the beginning of the container c.
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant FixedList.
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...
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
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.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
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)
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
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...