mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: HashTable and HashSet improvements
- unfriend HashSet, HashTable IO operators
- global min(), max(), minMax() functions taking a labelHashSet and an
optional limit. For example,
labelHashSet set = ...;
Info<< "min is " << min(set) << nl;
Info<< "max (non-negative) " << max(set, 0) << nl;
- make HashTable iterator '->' dereferencing more consistent by also
supporting non-pointer types as well.
- read HashTable values in-situ to avoid copying
This commit is contained in:
@ -32,6 +32,7 @@ Description
|
|||||||
#include "HashOps.H"
|
#include "HashOps.H"
|
||||||
#include "HashSet.H"
|
#include "HashSet.H"
|
||||||
#include "Map.H"
|
#include "Map.H"
|
||||||
|
#include "MinMax.H"
|
||||||
#include "labelPairHashes.H"
|
#include "labelPairHashes.H"
|
||||||
#include "FlatOutput.H"
|
#include "FlatOutput.H"
|
||||||
|
|
||||||
@ -184,6 +185,9 @@ int main(int argc, char *argv[])
|
|||||||
1, 11, 42
|
1, 11, 42
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Info<<"Set with min/max:" << minMax(setB)
|
||||||
|
<< " min:" << min(setB) << " max:" << max(setB) << nl;
|
||||||
|
|
||||||
setB = FixedList<label, 4>({1, 2, 3, 4});
|
setB = FixedList<label, 4>({1, 2, 3, 4});
|
||||||
setB = {1, 2, 4};
|
setB = {1, 2, 4};
|
||||||
setB = List<label>({1, 2, 4});
|
setB = List<label>({1, 2, 4});
|
||||||
|
|||||||
@ -261,14 +261,24 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
labelList list1(identity(4, -4));
|
labelList list1(identity(4, -4));
|
||||||
|
|
||||||
Info<<"move insert " << list1 << nl;
|
Info<< "move insert " << list1 << nl;
|
||||||
|
|
||||||
ltable1.insert("pqr", std::move(list1));
|
ltable1.insert("pqr", std::move(list1));
|
||||||
|
|
||||||
Info<<"after insert " << list1 << nl;
|
Info<< "after insert " << list1 << nl;
|
||||||
|
|
||||||
Info<< nl << "HashTable<labelList>: "
|
Info<< nl << "HashTable<labelList>: "
|
||||||
<< ltable1 << nl;
|
<< ltable1 << nl;
|
||||||
|
|
||||||
|
|
||||||
|
// Use '->' dereferencing
|
||||||
|
const auto iter = ltable1.cfind("ghi");
|
||||||
|
|
||||||
|
if (iter)
|
||||||
|
{
|
||||||
|
Info<< "got with " << iter->size() << nl;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "\nEnd\n" << endl;
|
Info<< "\nEnd\n" << endl;
|
||||||
|
|||||||
@ -171,6 +171,7 @@ containers/Bits/bitSet/bitSetIO.C
|
|||||||
containers/Bits/BitOps/BitOps.C
|
containers/Bits/BitOps/BitOps.C
|
||||||
containers/Bits/PackedList/PackedListCore.C
|
containers/Bits/PackedList/PackedListCore.C
|
||||||
containers/HashTables/HashOps/HashOps.C
|
containers/HashTables/HashOps/HashOps.C
|
||||||
|
containers/HashTables/HashSet/hashSets.C
|
||||||
containers/HashTables/HashTable/HashTableCore.C
|
containers/HashTables/HashTable/HashTableCore.C
|
||||||
containers/Lists/SortableList/ParSortableListName.C
|
containers/Lists/SortableList/ParSortableListName.C
|
||||||
containers/Lists/ListOps/ListOps.C
|
containers/Lists/ListOps/ListOps.C
|
||||||
|
|||||||
@ -73,10 +73,7 @@ namespace Foam
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
template<class Key, class Hash> class HashSet;
|
template<class T> class MinMax;
|
||||||
|
|
||||||
template<class Key, class Hash>
|
|
||||||
Ostream& operator<<(Ostream& os, const HashSet<Key, Hash>& tbl);
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
@ -380,15 +377,6 @@ public:
|
|||||||
inline this_type& operator-=(const this_type& rhs);
|
inline this_type& operator-=(const this_type& rhs);
|
||||||
|
|
||||||
|
|
||||||
// IOstream Operator
|
|
||||||
|
|
||||||
friend Ostream& operator<< <Key, Hash>
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const HashSet<Key, Hash>& tbl
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Housekeeping
|
// Housekeeping
|
||||||
|
|
||||||
//- Not applicable for HashSet
|
//- Not applicable for HashSet
|
||||||
@ -418,8 +406,36 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Typedefs
|
||||||
|
|
||||||
|
//- A HashSet with word keys.
|
||||||
|
typedef HashSet<word> wordHashSet;
|
||||||
|
|
||||||
|
//- A HashSet with label keys and label hasher.
|
||||||
|
typedef HashSet<label, Hash<label>> labelHashSet;
|
||||||
|
|
||||||
|
|
||||||
|
// Global Functions
|
||||||
|
|
||||||
|
//- Find the min value in labelHashSet, optionally limited by second argument.
|
||||||
|
// For an empty set, returns the second argument (eg, labelMax).
|
||||||
|
label min(const labelHashSet& set, label minValue = labelMax);
|
||||||
|
|
||||||
|
//- Find the max value in labelHashSet, optionally limited by second argument.
|
||||||
|
// For an empty set, returns the second argument (eg, labelMin).
|
||||||
|
label max(const labelHashSet& set, label maxValue = labelMin);
|
||||||
|
|
||||||
|
//- Find the min/max values of labelHashSet
|
||||||
|
MinMax<label> minMax(const labelHashSet& set);
|
||||||
|
|
||||||
|
|
||||||
// Global Operators
|
// Global Operators
|
||||||
|
|
||||||
|
//- Write the list of HashSet keys
|
||||||
|
template<class Key, class Hash>
|
||||||
|
Ostream& operator<<(Ostream& os, const HashSet<Key, Hash>& tbl);
|
||||||
|
|
||||||
|
|
||||||
//- Combine entries from HashSets
|
//- Combine entries from HashSets
|
||||||
template<class Key, class Hash>
|
template<class Key, class Hash>
|
||||||
HashSet<Key, Hash> operator|
|
HashSet<Key, Hash> operator|
|
||||||
@ -447,13 +463,6 @@ HashSet<Key, Hash> operator^
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//- A HashSet with word keys.
|
|
||||||
typedef HashSet<word> wordHashSet;
|
|
||||||
|
|
||||||
//- A HashSet with label keys and label hasher.
|
|
||||||
typedef HashSet<label, Hash<label>> labelHashSet;
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -104,12 +104,6 @@ template<class T> class UList;
|
|||||||
template<class T, unsigned N> class FixedList;
|
template<class T, unsigned N> class FixedList;
|
||||||
template<class T, class Key, class Hash> class HashTable;
|
template<class T, class Key, class Hash> class HashTable;
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
|
||||||
Istream& operator>>(Istream& is, HashTable<T, Key, Hash>& tbl);
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
|
||||||
Ostream& operator<<(Ostream& os, const HashTable<T, Key, Hash>& tbl);
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class HashTable Declaration
|
Class HashTable Declaration
|
||||||
@ -149,10 +143,6 @@ class HashTable
|
|||||||
// No checks for zero-sized tables.
|
// No checks for zero-sized tables.
|
||||||
inline label hashKeyIndex(const Key& key) const;
|
inline label hashKeyIndex(const Key& key) const;
|
||||||
|
|
||||||
//- Read entry (key, val) and assign
|
|
||||||
// \return True if the new entry was set.
|
|
||||||
bool addEntry(Istream& is, const bool overwrite = false);
|
|
||||||
|
|
||||||
//- Assign a new hash-entry to a possibly already existing key.
|
//- Assign a new hash-entry to a possibly already existing key.
|
||||||
// \return True if the new entry was set.
|
// \return True if the new entry was set.
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
@ -732,7 +722,7 @@ public:
|
|||||||
inline reference operator*() const { return this->val(); }
|
inline reference operator*() const { return this->val(); }
|
||||||
inline reference operator()() const { return this->val(); }
|
inline reference operator()() const { return this->val(); }
|
||||||
|
|
||||||
//- For pointer types, allow direct pointer dereferencing
|
//- Direct pointer dereferencing (pointer types)
|
||||||
template<class TypeT = T>
|
template<class TypeT = T>
|
||||||
typename std::enable_if
|
typename std::enable_if
|
||||||
<
|
<
|
||||||
@ -740,6 +730,14 @@ public:
|
|||||||
T
|
T
|
||||||
>::type operator->() const { return this->val(); }
|
>::type operator->() const { return this->val(); }
|
||||||
|
|
||||||
|
//- Address of iterated value (non-pointer types)
|
||||||
|
template<class TypeT = T>
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
!Detail::isPointer<TypeT>::value,
|
||||||
|
T*
|
||||||
|
>::type operator->() const { return &(this->val()); }
|
||||||
|
|
||||||
inline iterator& operator++();
|
inline iterator& operator++();
|
||||||
inline iterator operator++(int);
|
inline iterator operator++(int);
|
||||||
};
|
};
|
||||||
@ -802,7 +800,7 @@ public:
|
|||||||
inline reference operator*() const { return this->val(); }
|
inline reference operator*() const { return this->val(); }
|
||||||
inline reference operator()() const { return this->val(); }
|
inline reference operator()() const { return this->val(); }
|
||||||
|
|
||||||
//- For pointer types, allow direct pointer dereferencing
|
//- Direct pointer dereferencing (pointer types)
|
||||||
template<class TypeT = T>
|
template<class TypeT = T>
|
||||||
typename std::enable_if
|
typename std::enable_if
|
||||||
<
|
<
|
||||||
@ -810,6 +808,14 @@ public:
|
|||||||
const T
|
const T
|
||||||
>::type operator->() const { return this->val(); }
|
>::type operator->() const { return this->val(); }
|
||||||
|
|
||||||
|
//- Address of iterated value (non-pointer types)
|
||||||
|
template<class TypeT = T>
|
||||||
|
typename std::enable_if
|
||||||
|
<
|
||||||
|
!Detail::isPointer<TypeT>::value,
|
||||||
|
const T*
|
||||||
|
>::type operator->() const { return &(this->val()); }
|
||||||
|
|
||||||
inline const_iterator& operator++();
|
inline const_iterator& operator++();
|
||||||
inline const_iterator operator++(int);
|
inline const_iterator operator++(int);
|
||||||
|
|
||||||
@ -911,24 +917,18 @@ public:
|
|||||||
//- when length exceeds shortLen.
|
//- when length exceeds shortLen.
|
||||||
// Using '0' suppresses line-breaks entirely.
|
// Using '0' suppresses line-breaks entirely.
|
||||||
Ostream& writeKeys(Ostream& os, const label shortLen=0) const;
|
Ostream& writeKeys(Ostream& os, const label shortLen=0) const;
|
||||||
|
|
||||||
|
|
||||||
// IOstream Operator
|
|
||||||
|
|
||||||
friend Istream& operator>> <T, Key, Hash>
|
|
||||||
(
|
|
||||||
Istream& is,
|
|
||||||
HashTable<T, Key, Hash>& tbl
|
|
||||||
);
|
|
||||||
|
|
||||||
friend Ostream& operator<< <T, Key, Hash>
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const HashTable<T, Key, Hash>& tbl
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// IOstream Operators
|
||||||
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
Istream& operator>>(Istream& is, HashTable<T, Key, Hash>& tbl);
|
||||||
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
Ostream& operator<<(Ostream& os, const HashTable<T, Key, Hash>& tbl);
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -29,28 +29,6 @@ License
|
|||||||
#include "Istream.H"
|
#include "Istream.H"
|
||||||
#include "Ostream.H"
|
#include "Ostream.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
|
||||||
bool Foam::HashTable<T, Key, Hash>::addEntry(Istream& is, const bool overwrite)
|
|
||||||
{
|
|
||||||
typename node_type::key_type key;
|
|
||||||
typename node_type::mapped_type val;
|
|
||||||
|
|
||||||
is >> key >> val;
|
|
||||||
|
|
||||||
const bool ok = this->setEntry(overwrite, key, val);
|
|
||||||
|
|
||||||
is.fatalCheck
|
|
||||||
(
|
|
||||||
"HashTable::addEntry(Istream&) : "
|
|
||||||
"reading entry"
|
|
||||||
);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
@ -168,11 +146,11 @@ template<class T, class Key, class Hash>
|
|||||||
Foam::Istream& Foam::operator>>
|
Foam::Istream& Foam::operator>>
|
||||||
(
|
(
|
||||||
Istream& is,
|
Istream& is,
|
||||||
HashTable<T, Key, Hash>& L
|
HashTable<T, Key, Hash>& tbl
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Anull existing table
|
// Anull existing table
|
||||||
L.clear();
|
tbl.clear();
|
||||||
|
|
||||||
is.fatalCheck(FUNCTION_NAME);
|
is.fatalCheck(FUNCTION_NAME);
|
||||||
|
|
||||||
@ -193,24 +171,32 @@ Foam::Istream& Foam::operator>>
|
|||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
if (2*len > L.capacity_)
|
if (delimiter != token::BEGIN_LIST)
|
||||||
{
|
|
||||||
L.resize(2*len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (delimiter == token::BEGIN_LIST)
|
|
||||||
{
|
|
||||||
for (label i=0; i<len; ++i)
|
|
||||||
{
|
|
||||||
L.addEntry(is);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(is)
|
FatalIOErrorInFunction(is)
|
||||||
<< "incorrect first token, '(', found " << firstToken.info()
|
<< "incorrect first token, '(', found " << firstToken.info()
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (2*len > tbl.capacity())
|
||||||
|
{
|
||||||
|
tbl.resize(2*len);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label i=0; i<len; ++i)
|
||||||
|
{
|
||||||
|
Key key;
|
||||||
|
|
||||||
|
is >> key; // Read the key
|
||||||
|
T& val = tbl(key); // Insert nameless T() into table
|
||||||
|
is >> val; // Read directly into the table value
|
||||||
|
|
||||||
|
is.fatalCheck
|
||||||
|
(
|
||||||
|
"operator>>(Istream&, HashTable&) : "
|
||||||
|
"reading entry"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read end of contents
|
// Read end of contents
|
||||||
@ -236,7 +222,17 @@ Foam::Istream& Foam::operator>>
|
|||||||
{
|
{
|
||||||
is.putBack(lastToken);
|
is.putBack(lastToken);
|
||||||
|
|
||||||
L.addEntry(is);
|
Key key;
|
||||||
|
|
||||||
|
is >> key; // Read the key
|
||||||
|
T& val = tbl(key); // Insert nameless T() into table
|
||||||
|
is >> val; // Read directly into the table value
|
||||||
|
|
||||||
|
is.fatalCheck
|
||||||
|
(
|
||||||
|
"operator>>(Istream&, HashTable&) : "
|
||||||
|
"reading entry"
|
||||||
|
);
|
||||||
|
|
||||||
is >> lastToken;
|
is >> lastToken;
|
||||||
}
|
}
|
||||||
@ -250,7 +246,6 @@ Foam::Istream& Foam::operator>>
|
|||||||
}
|
}
|
||||||
|
|
||||||
is.fatalCheck(FUNCTION_NAME);
|
is.fatalCheck(FUNCTION_NAME);
|
||||||
|
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user