29 #ifndef Foam_HashTable_C 30 #define Foam_HashTable_C 39 template<
class T,
class Key,
class Hash>
46 template<
class T,
class Key,
class Hash>
56 table_ =
new node_type*[capacity_];
57 for (label i=0; i < capacity_; ++i)
65 template<
class T,
class Key,
class Hash>
68 HashTable<
T, Key, Hash>(ht.capacity_)
70 for (const_iterator iter = ht.cbegin(); iter != ht.cend(); ++iter)
72 insert(iter.key(), iter.val());
77 template<
class T,
class Key,
class Hash>
82 capacity_(rhs.capacity_),
91 template<
class T,
class Key,
class Hash>
94 std::initializer_list<std::pair<Key, T>> list
99 for (
const auto& keyval : list)
101 set(keyval.first, keyval.second);
108 template<
class T,
class Key,
class Hash>
121 template<
class T,
class Key,
class Hash>
124 List<Key> list(size_);
127 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
129 list[
count++] = iter.key();
136 template<
class T,
class Key,
class Hash>
139 List<Key> list(this->
toc());
146 template<
class T,
class Key,
class Hash>
147 template<
class Compare>
160 template<
class T,
class Key,
class Hash>
168 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
179 template<
class T,
class Key,
class Hash>
187 template<
class T,
class Key,
class Hash>
195 for (iterator iter =
begin(); iter !=
end(); ++iter)
197 result.set(
count++, iter.node());
207 template<
class T,
class Key,
class Hash>
208 template<
class UnaryPredicate>
211 const UnaryPredicate& pred,
218 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
222 list[
count++] = iter.key();
233 template<
class T,
class Key,
class Hash>
234 template<
class UnaryPredicate>
237 const UnaryPredicate& pred,
244 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
248 list[
count++] = iter.key();
259 template<
class T,
class Key,
class Hash>
260 template<
class BinaryPredicate>
263 const BinaryPredicate& pred,
270 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
274 list[
count++] = iter.key();
285 template<
class T,
class Key,
class Hash>
286 template<
class UnaryPredicate>
289 const UnaryPredicate& pred,
295 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
307 template<
class T,
class Key,
class Hash>
308 template<
class UnaryPredicate>
311 const UnaryPredicate& pred,
317 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
329 template<
class T,
class Key,
class Hash>
330 template<
class BinaryPredicate>
333 const BinaryPredicate& pred,
339 for (const_iterator iter =
cbegin(); iter !=
cend(); ++iter)
351 template<
class T,
class Key,
class Hash>
352 template<
class... Args>
355 const bool overwrite,
366 const label index = hashKeyIndex(
key);
368 node_type* curr =
nullptr;
369 node_type* prev =
nullptr;
371 for (node_type* ep = table_[index]; ep; ep = ep->next_)
373 if (
key == ep->key())
385 new node_type(table_[index],
key, std::forward<Args>(
args)...);
388 if (0.8*capacity_ < size_)
390 if (capacity_ < maxTableSize)
resize(2*capacity_);
399 if (!node_type::stores_value())
404 node_type* ep = curr->next_;
411 ep =
new node_type(ep,
key, std::forward<Args>(
args)...);
433 template<
class T,
class Key,
class Hash>
444 const label index = hashKeyIndex(entry->key());
446 node_type* curr =
nullptr;
449 for (node_type* ep = table_[index]; ep; ep = ep->next_)
451 if (entry->key() == ep->key())
462 table_[index] = entry;
465 if (0.8*capacity_ < size_)
467 if (capacity_ < maxTableSize)
resize(2*capacity_);
473 <<
"Not inserting " <<
entry->key() <<
": already in table\n" 479 template<
class T,
class Key,
class Hash>
487 return iterator_erase(const_cast<iterator&>(iter));
491 template<
class T,
class Key,
class Hash>
495 return iterator_erase(iter);
499 template<
class T,
class Key,
class Hash>
500 template<
class InputIter>
511 const label nTotal = this->size();
512 changed < nTotal && first != last;
516 if (this->
erase(*first))
526 template<
class T,
class Key,
class Hash>
529 std::initializer_list<Key> keys
532 return erase(keys.begin(), keys.end());
536 template<
class T,
class Key,
class Hash>
547 template<
class T,
class Key,
class Hash>
557 template<
class T,
class Key,
class Hash>
558 template<
class AnyType,
class AnyHash>
564 const label nTotal = this->size();
567 if (other.
size() <= nTotal)
573 auto iter = other.
cbegin();
574 changed < nTotal && iter != other.
cend();
578 if (
erase(iter.key()))
589 iterator iter =
begin();
590 changed < nTotal && iter !=
end();
605 template<
class T,
class Key,
class Hash>
606 template<
class AnyType,
class AnyHash>
612 const label nTotal = this->size();
625 for (iterator iter =
begin(); iter !=
end(); ++iter)
638 template<
class T,
class Key,
class Hash>
641 const label newCapacity = HashTableCore::canonicalSize(sz);
642 const label oldCapacity = capacity_;
644 if (newCapacity == oldCapacity)
648 else if (!newCapacity)
654 <<
"HashTable contains " << size_
655 <<
" elements, cannot resize(0)" <<
nl;
673 auto oldTable = table_;
674 capacity_ = newCapacity;
676 table_ =
new node_type*[capacity_];
677 for (label i=0; i < capacity_; ++i)
684 for (label i = 0, nPending = size_; nPending && i < oldCapacity; ++i)
686 for (node_type* ep = oldTable[i]; ep; )
688 node_type* next = ep->next_;
692 const label newIdx = hashKeyIndex(ep->key());
694 ep->next_ = table_[newIdx];
701 oldTable[i] =
nullptr;
711 template<
class T,
class Key,
class Hash>
714 for (label i=0; size_ && i<capacity_; ++i)
716 for (node_type* ep = table_[i]; ep; )
718 node_type* next = ep->next_;
730 template<
class T,
class Key,
class Hash>
738 template<
class T,
class Key,
class Hash>
746 std::swap(size_, rhs.size_);
747 std::swap(capacity_, rhs.capacity_);
748 std::swap(table_, rhs.table_);
752 template<
class T,
class Key,
class Hash>
765 template<
class T,
class Key,
class Hash>
766 template<
class UnaryPredicate>
769 const UnaryPredicate& pred,
775 for (iterator iter =
begin(); iter !=
end(); ++iter)
780 (pred(iter.key()) ? pruning : !pruning)
792 template<
class T,
class Key,
class Hash>
793 template<
class UnaryPredicate>
796 const UnaryPredicate& pred,
802 for (iterator iter =
begin(); iter !=
end(); ++iter)
807 (pred(iter.val()) ? pruning : !pruning)
819 template<
class T,
class Key,
class Hash>
820 template<
class BinaryPredicate>
823 const BinaryPredicate& pred,
829 for (iterator iter =
begin(); iter !=
end(); ++iter)
834 (pred(iter.key(), iter.val()) ? pruning : !pruning)
846 template<
class T,
class Key,
class Hash>
851 if (node_type::stores_value())
854 for (iterator iter = source.begin(); iter != source.end(); ++iter)
856 if (!contains(iter.key()))
858 node_type* entry = source.iterator_extract(iter);
859 this->insert_node(entry);
868 for (iterator iter = source.begin(); iter != source.end(); ++iter)
870 if (emplace(iter.key()))
879 template<
class T,
class Key,
class Hash>
888 template<
class T,
class Key,
class Hash>
891 const HashTable<T, Key, Hash>& rhs
909 for (const_iterator iter = rhs.
cbegin(); iter != rhs.
cend(); ++iter)
916 template<
class T,
class Key,
class Hash>
919 std::initializer_list<std::pair<Key, T>> rhs
932 for (
const auto& keyval : rhs)
934 set(keyval.first, keyval.second);
939 template<
class T,
class Key,
class Hash>
942 HashTable<T, Key, Hash>&& rhs
954 template<
class T,
class Key,
class Hash>
961 if (size() != rhs.
size())
966 for (const_iterator iter = rhs.
cbegin(); iter != rhs.
cend(); ++iter)
968 const const_iterator other(this->cfind(iter.key()));
970 if (!other.good() || other.val() != iter.val())
980 template<
class T,
class Key,
class Hash>
990 template<
class T,
class Key,
class Hash>
997 if (rhs.
size() ||
this != &rhs)
1001 for (const_iterator iter = rhs.
cbegin(); iter != rhs.
cend(); ++iter)
1003 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)
patchWriters resize(patchIds.size())
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 resize(const label sz)
Resize the hash table for efficiency.
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...
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.
void swap(HashTable< T, Key, Hash > &rhs)
Swap contents into this table.
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()
Clear 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.
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...
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.
HashTable()
Default construct with default (128) table capacity.
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 transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
UPtrList< const node_type > sorted() const
Const access to the hash-table contents in sorted order (sorted by keys).
label filterKeys(const UnaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their keys.
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()
Clear the table entries 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...