mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add missing Hash function for List/UList (issue #966)
- there were previously no hashing mechanisms for lists so they would fall back to the definition for primitives and hash the memory location of the allocated List object. - provide a UList::Hash<> sub-class for inheritance, and also a global specialization for UList<T>, List<T> such that the hash value for List<List<T>> cascades properly. - provide similar function in triFace to ensure that it remains similar in behaviour to face. - added SymmHash to Pair, for use when order is unimportant. STYLE: use string::hash() more consistently - no particular reason to use Hash<word>() which forwards to string::hash() anyhow
This commit is contained in:
@ -54,20 +54,13 @@ class multiphaseSystem
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef
|
||||
HashTable
|
||||
<
|
||||
volScalarField::Internal,
|
||||
word,
|
||||
word::hash
|
||||
>
|
||||
SuSpTable;
|
||||
typedef HashTable<volScalarField::Internal> SuSpTable;
|
||||
|
||||
typedef HashTable<scalar, phasePairKey, phasePairKey::hash>
|
||||
scalarTable;
|
||||
|
||||
typedef HashTable<surfaceScalarField, word, word::hash>
|
||||
compressionFluxTable;
|
||||
typedef HashTable<surfaceScalarField> compressionFluxTable;
|
||||
|
||||
|
||||
// Protected data
|
||||
|
||||
|
||||
@ -75,8 +75,7 @@ public:
|
||||
phasePairTable;
|
||||
|
||||
|
||||
typedef
|
||||
HashTable<autoPtr<phaseModel>, word, word::hash> phaseModelTable;
|
||||
typedef HashTable<autoPtr<phaseModel>> phaseModelTable;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@ -139,13 +139,16 @@ int main(int argc, char *argv[])
|
||||
FixedList<label, 4> list1{2, 3, 4, 5};
|
||||
|
||||
Info<< "list1:" << list1
|
||||
<< " hash:" << FixedList<label, 4>::Hash<>()(list1) << nl;
|
||||
<< " hash:" << FixedList<label,4>::Hash<>()(list1) << nl
|
||||
<< " hash:" << Hash<FixedList<label,4>>()(list1) << nl;
|
||||
|
||||
label a[4] = {0, 1, 2, 3};
|
||||
FixedList<label, 4> list2(a);
|
||||
|
||||
Info<< "list2:" << list2
|
||||
<< " hash:" << FixedList<label, 4>::Hash<>()(list2) << nl;
|
||||
<< " hash:" << FixedList<label,4>::Hash<>()(list2) << nl
|
||||
<< " hash:" << Hash<FixedList<label,4>>()(list2) << nl;
|
||||
|
||||
|
||||
// Using FixedList for content too
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -36,6 +36,7 @@ Description
|
||||
#include "labelList.H"
|
||||
#include "labelPair.H"
|
||||
#include "edgeList.H"
|
||||
#include "faceList.H"
|
||||
#include "triFaceList.H"
|
||||
|
||||
#include "Hash.H"
|
||||
@ -50,7 +51,7 @@ void infoHashString
|
||||
{
|
||||
if (modulus)
|
||||
{
|
||||
Info<< "basic string hashing (mod " << label(modulus) << ")" << endl;
|
||||
Info<< "basic string hashing (mod " << label(modulus) << ")" << nl;
|
||||
|
||||
for (const auto& str : lst)
|
||||
{
|
||||
@ -72,6 +73,190 @@ void infoHashString
|
||||
}
|
||||
|
||||
|
||||
|
||||
void reportHashList(const UList<string>& list)
|
||||
{
|
||||
Info<< "contiguous = " << contiguous<string>() << nl << nl;
|
||||
|
||||
for (const string& val : list)
|
||||
{
|
||||
unsigned hash1 = string::hash()(val);
|
||||
|
||||
Info<< hex << hash1 << ": " << val << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reportHashList(const UList<label>& list)
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<label>() << nl << nl;
|
||||
|
||||
for (const label val : list)
|
||||
{
|
||||
// Direct value
|
||||
unsigned hash1 = Hash<label>()(val);
|
||||
|
||||
// Hashed byte-wise
|
||||
unsigned hash2 = Hash<label>()(val, 0);
|
||||
|
||||
Info<< hex << hash1
|
||||
<< " (seeded: " << hash2 << ")"
|
||||
<< ": " << dec << val << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reportHashList(const UList<face>& list)
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<label>() << nl << nl;
|
||||
|
||||
for (const face& f : list)
|
||||
{
|
||||
// Direct value
|
||||
unsigned hash1 = face::Hash<>()(f);
|
||||
|
||||
unsigned hash2 = Hash<face>()(f);
|
||||
|
||||
Info<< hex << "face::Hash<> " << hash1
|
||||
<< " Hash<face> " << hash2
|
||||
<< ": " << dec << flatOutput(f) << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reportHashList(const UList<labelList>& list)
|
||||
{
|
||||
for (const labelList& val : list)
|
||||
{
|
||||
unsigned hash1 = Hasher
|
||||
(
|
||||
val.cdata(),
|
||||
val.size() * sizeof(label)
|
||||
);
|
||||
|
||||
unsigned hash2 = Hash<labelList>()(val);
|
||||
unsigned hash2b = labelList::Hash<>()(val);
|
||||
|
||||
Info<< hex << hash1 << " or " << hash2
|
||||
<< "(" << hash2b << ") "
|
||||
<< ": " << dec << val << nl;
|
||||
}
|
||||
|
||||
unsigned hash2 = Hash<labelListList>()(list);
|
||||
unsigned hash2bad = HasherT(list);
|
||||
|
||||
Info<< hex << hash2 << " : " << dec << flatOutput(list) << nl
|
||||
<< hex << hash2bad << " as direct hash would be wrong"
|
||||
<< dec << nl;
|
||||
}
|
||||
|
||||
|
||||
typedef Pair<word> wordPair;
|
||||
|
||||
void reportHashList(const UList<wordPair>& list)
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<wordPair>() << nl << nl;
|
||||
|
||||
for (const wordPair& pr : list)
|
||||
{
|
||||
unsigned hash1 = Hash<wordPair>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2 = wordPair::Hash<>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2sym = wordPair::SymmHash<>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash3 = Hash<FixedList<word,2>>()(pr);
|
||||
|
||||
Info<< hex << hash1 << " (as FixedList: " << hash2
|
||||
<< ") or " << hash3
|
||||
<< " symm-hash:" << hash2sym
|
||||
<< " : "<< dec << flatOutput(pr) << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reportHashList(const UList<labelPair>& list)
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<labelPair>() << nl << nl;
|
||||
|
||||
for (const labelPair& pr : list)
|
||||
{
|
||||
unsigned hash1 = Hash<labelPair>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2 = labelPair::Hash<>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash3 = Hash<labelPair>()(pr);
|
||||
|
||||
Info<< hex << hash1 << " (as FixedList: " << hash2
|
||||
<< ") or " << hash3
|
||||
<< " : "<< dec << pr << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reportHashList(const UList<labelPairPair>& list)
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<labelPairPair>() << nl << nl;
|
||||
|
||||
for (const labelPairPair& pr : list)
|
||||
{
|
||||
unsigned hash1 = Hash<labelPairPair>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2 = labelPairPair::Hash<>()(pr);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash3 = Hash<labelPairPair>()(pr);
|
||||
|
||||
Info<< hex << hash1 << " (as FixedList: " << hash2
|
||||
<< ") or " << hash3
|
||||
<< " : "<< dec << pr << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reportHashList(const UList<edge>& list)
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<edge>() << nl << nl;
|
||||
|
||||
for (const edge& e : list)
|
||||
{
|
||||
unsigned hash1 = Hash<edge>()(e);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2 = labelPair::Hash<>()(e);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash3 = Hash<labelPair>()(e);
|
||||
|
||||
Info<< hex << hash1 << " (as FixedList: " << hash2
|
||||
<< ") or " << hash3
|
||||
<< " : "<< dec << e << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reportHashList(const UList<triFace>& list)
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<triFace>() << nl << nl;
|
||||
|
||||
for (const triFace& f : list)
|
||||
{
|
||||
// direct value
|
||||
unsigned hash1 = Hash<triFace>()(f);
|
||||
unsigned hash2 = FixedList<label, 3>::Hash<>()(f);
|
||||
|
||||
Info<< hex << hash1 << " (as FixedList: " << hash2
|
||||
<< "): " << dec << f << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
@ -81,114 +266,74 @@ int main(int argc, char *argv[])
|
||||
|
||||
IFstream is("hashingTests");
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
Info<< "No \"hashingTests\" file found ...\n";
|
||||
}
|
||||
|
||||
while (is.good())
|
||||
{
|
||||
const word listType(is);
|
||||
|
||||
Info<< endl;
|
||||
IOobject::writeDivider(Info) << listType << endl;
|
||||
if (listType.empty()) continue;
|
||||
|
||||
Info<< nl;
|
||||
IOobject::writeDivider(Info) << listType << nl;
|
||||
|
||||
if (listType == "stringList")
|
||||
{
|
||||
Info<< "contiguous = " << contiguous<string>() << endl << endl;
|
||||
|
||||
stringList lst(is);
|
||||
|
||||
forAll(lst, i)
|
||||
{
|
||||
unsigned hash1 = string::hash()(lst[i]);
|
||||
|
||||
Info<< hex << hash1 << ": " << lst[i] << endl;
|
||||
}
|
||||
stringList list(is);
|
||||
|
||||
reportHashList(list);
|
||||
}
|
||||
else if (listType == "labelList")
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<label>() << endl << endl;
|
||||
|
||||
labelList lst(is);
|
||||
|
||||
forAll(lst, i)
|
||||
{
|
||||
// direct value
|
||||
unsigned hash1 = Hash<label>()(lst[i]);
|
||||
|
||||
// hashed byte-wise
|
||||
unsigned hash2 = Hash<label>()(lst[i], 0);
|
||||
|
||||
Info<< hex << hash1
|
||||
<< " (seeded: " << hash2 << ")"
|
||||
<< ": " << dec << lst[i] << endl;
|
||||
}
|
||||
|
||||
if (contiguous<label>())
|
||||
{
|
||||
unsigned hash3 = Hasher
|
||||
(
|
||||
lst.cdata(),
|
||||
lst.size() * sizeof(label)
|
||||
);
|
||||
|
||||
Info<<"contiguous hashed value " << hex << hash3 << endl;
|
||||
}
|
||||
labelList list(is);
|
||||
reportHashList(list);
|
||||
}
|
||||
else if (listType == "faceList")
|
||||
{
|
||||
faceList list(is);
|
||||
reportHashList(list);
|
||||
}
|
||||
else if (listType == "labelListList")
|
||||
{
|
||||
List<List<label>> lst(is);
|
||||
|
||||
forAll(lst, i)
|
||||
{
|
||||
unsigned hash1 = Hasher
|
||||
(
|
||||
lst[i].cdata(),
|
||||
lst[i].size() * sizeof(label)
|
||||
);
|
||||
|
||||
Info<< hex << hash1
|
||||
<< ": " << dec << lst[i] << endl;
|
||||
}
|
||||
|
||||
List<labelList> list(is);
|
||||
reportHashList(list);
|
||||
}
|
||||
else if (listType == "wordPairList")
|
||||
{
|
||||
List<wordPair> list(is);
|
||||
reportHashList(list);
|
||||
}
|
||||
else if (listType == "labelPairList")
|
||||
{
|
||||
labelPairList list(is);
|
||||
reportHashList(list);
|
||||
}
|
||||
else if (listType == "labelPairPairList")
|
||||
{
|
||||
List<labelPairPair> list(is);
|
||||
reportHashList(list);
|
||||
}
|
||||
else if (listType == "edgeList")
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<edge>() << endl << endl;
|
||||
|
||||
edgeList lst(is);
|
||||
|
||||
forAll(lst, i)
|
||||
{
|
||||
unsigned hash1 = Hash<edge>()(lst[i]);
|
||||
|
||||
// as FixedList
|
||||
unsigned hash2 = labelPair::Hash<>()(lst[i]);
|
||||
|
||||
Info<< hex << hash1 << " (as FixedList: " << hash2
|
||||
<< "): " << dec << lst[i] << endl;
|
||||
}
|
||||
edgeList list(is);
|
||||
reportHashList(list);
|
||||
}
|
||||
else if (listType == "triFaceList")
|
||||
{
|
||||
Info<<"contiguous = " << contiguous<triFace>() << endl << endl;
|
||||
|
||||
triFaceList lst(is);
|
||||
|
||||
forAll(lst, i)
|
||||
{
|
||||
// direct value
|
||||
unsigned hash1 = Hash<triFace>()(lst[i]);
|
||||
unsigned hash2 = FixedList<label, 3>::Hash<>()(lst[i]);
|
||||
|
||||
Info<< hex << hash1 << " (as FixedList: " << hash2
|
||||
<< "): " << dec << lst[i] << endl;
|
||||
}
|
||||
triFaceList list(is);
|
||||
reportHashList(list);
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "unknown type: " << listType << endl;
|
||||
Info<< "unknown type: " << listType << nl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << nl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ labelList
|
||||
-1
|
||||
-10
|
||||
-100
|
||||
100
|
||||
)
|
||||
|
||||
labelListList
|
||||
@ -34,6 +35,16 @@ labelListList
|
||||
(0 1)
|
||||
(100 1000)
|
||||
(0 1 100 1000)
|
||||
(100 1000)
|
||||
)
|
||||
|
||||
faceList
|
||||
(
|
||||
(0 1 2 3 4 5)
|
||||
(5 4 3 1 2 0)
|
||||
(0 1 2 3 4 5)
|
||||
(100 0 15)
|
||||
(15 0 100)
|
||||
)
|
||||
|
||||
// edges are hashed commutatively
|
||||
@ -45,6 +56,7 @@ edgeList
|
||||
(100 45)
|
||||
(128 1000)
|
||||
(1000 128)
|
||||
(100 45)
|
||||
)
|
||||
|
||||
// triFaces are also hashed commutatively (via multiply/add)
|
||||
@ -56,4 +68,34 @@ triFaceList
|
||||
)
|
||||
|
||||
|
||||
labelPairList
|
||||
(
|
||||
(0 1)
|
||||
(1 0)
|
||||
(45 100)
|
||||
(100 45)
|
||||
(128 1000)
|
||||
(1000 128)
|
||||
(100 45)
|
||||
)
|
||||
|
||||
|
||||
labelPairPairList
|
||||
(
|
||||
((0 1) (1 0))
|
||||
((45 100) (100 45))
|
||||
((128 1000) (1000 128))
|
||||
((45 100) (100 45))
|
||||
)
|
||||
|
||||
|
||||
wordPairList
|
||||
(
|
||||
("Yes" "No")
|
||||
("True" "False")
|
||||
("No" "Yes")
|
||||
("False" "True")
|
||||
)
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -598,6 +598,20 @@ int main(int argc, char *argv[])
|
||||
<< "-wordList: " << flatOutput(wLst) << nl
|
||||
<< "-stringList: " << flatOutput(sLst) << endl;
|
||||
|
||||
// Hash values
|
||||
{
|
||||
labelList list1(identity(5));
|
||||
labelList list2(identity(5));
|
||||
|
||||
Info<<"hash of " << flatOutput(list1)
|
||||
<< " = " << Hash<labelList>()(list1) << " or "
|
||||
<< labelList::Hash<>()(list1) << nl;
|
||||
|
||||
Info<<"hash of " << flatOutput(list2) << " = "
|
||||
<< Hash<labelList>()(list2) << " or "
|
||||
<< labelList::Hash<>()(list2) << nl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -54,24 +54,8 @@ using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
template<>
|
||||
inline unsigned Hash<face>::operator()(const face& t, unsigned seed) const
|
||||
{
|
||||
return Hasher(t.cdata(),t.size()*sizeof(label), seed);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned Hash<face>::operator()(const face& t) const
|
||||
{
|
||||
return Hash<face>::operator()(t, 0);
|
||||
}
|
||||
}
|
||||
|
||||
const string SEPARATOR(" -1");
|
||||
|
||||
|
||||
bool isSeparator(const std::string& line)
|
||||
{
|
||||
return line.substr(0, 6) == SEPARATOR;
|
||||
@ -861,7 +845,7 @@ int main(int argc, char *argv[])
|
||||
Map<label> faceToCell[2];
|
||||
|
||||
{
|
||||
HashTable<label, face, Hash<face>> faceToFaceID(boundaryFaces.size());
|
||||
HashTable<label, face, face::Hash<>> faceToFaceID(boundaryFaces.size());
|
||||
forAll(boundaryFaces, facei)
|
||||
{
|
||||
SortableList<label> sortedVerts(boundaryFaces[facei]);
|
||||
@ -874,12 +858,11 @@ int main(int argc, char *argv[])
|
||||
forAll(faces, i)
|
||||
{
|
||||
SortableList<label> sortedVerts(faces[i]);
|
||||
HashTable<label, face, Hash<face>>::const_iterator fnd =
|
||||
faceToFaceID.find(face(sortedVerts));
|
||||
const auto fnd = faceToFaceID.find(face(sortedVerts));
|
||||
|
||||
if (fnd != faceToFaceID.end())
|
||||
if (fnd.found())
|
||||
{
|
||||
label facei = fnd();
|
||||
label facei = *fnd;
|
||||
int stat = face::compare(faces[i], boundaryFaces[facei]);
|
||||
|
||||
if (stat == 1)
|
||||
|
||||
@ -166,7 +166,7 @@ int main(int argc, char *argv[])
|
||||
label maxPatch = 0;
|
||||
|
||||
// Boundary faces as three vertices
|
||||
HashTable<label, triFace, Hash<triFace>> vertsToBoundary(nFaces);
|
||||
HashTable<label, triFace, triFace::Hash<>> vertsToBoundary(nFaces);
|
||||
|
||||
forAll(boundaryFaces, facei)
|
||||
{
|
||||
@ -215,12 +215,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Is there any boundary face with same vertices?
|
||||
// (uses commutative hash)
|
||||
HashTable<label, triFace, Hash<triFace>>::iterator iter =
|
||||
vertsToBoundary.find(triFace(f[0], f[1], f[2]));
|
||||
auto iter = vertsToBoundary.find(triFace(f[0], f[1], f[2]));
|
||||
|
||||
if (iter != vertsToBoundary.end())
|
||||
if (iter.found())
|
||||
{
|
||||
label facei = iter();
|
||||
label facei = iter.object();
|
||||
const triFace& tri = iter.key();
|
||||
|
||||
// Determine orientation of tri v.s. cell centre.
|
||||
|
||||
@ -41,9 +41,10 @@ SourceFiles
|
||||
#include "label.H"
|
||||
#include "uLabel.H"
|
||||
#include "zero.H"
|
||||
#include "Hash.H"
|
||||
#include "contiguous.H"
|
||||
#include "autoPtr.H"
|
||||
#include "Swap.H"
|
||||
#include "HashFwd.H"
|
||||
#include "SLListFwd.H"
|
||||
|
||||
#include <initializer_list>
|
||||
@ -137,19 +138,6 @@ public:
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
|
||||
//- Hashing function class.
|
||||
// Use Hasher directly for contiguous data. Otherwise hash incrementally.
|
||||
template<class HashT=Hash<T>>
|
||||
struct Hash
|
||||
{
|
||||
inline unsigned operator()
|
||||
(
|
||||
const FixedList<T, Size>& list,
|
||||
unsigned seed = 0
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
// Static Member Functions
|
||||
|
||||
//- Return a null FixedList
|
||||
@ -438,10 +426,38 @@ public:
|
||||
Ostream& os,
|
||||
const FixedList<T, Size>& list
|
||||
);
|
||||
|
||||
|
||||
// Hashing
|
||||
|
||||
//- Hashing function class for FixedList
|
||||
// Normally use the global Hash specialization, but can also use
|
||||
// this one for inheritance in sub-classes
|
||||
template<class HashT=Foam::Hash<T>>
|
||||
struct Hash
|
||||
{
|
||||
inline unsigned operator()
|
||||
(
|
||||
const FixedList<T, Size>& obj,
|
||||
unsigned seed=0
|
||||
) const
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
return Hasher(obj.cdata(), Size*sizeof(T), seed);
|
||||
}
|
||||
|
||||
for (const T& val : obj)
|
||||
{
|
||||
seed = HashT()(val, seed);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Global Functions
|
||||
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
||||
|
||||
//- Swap FixedList contents - see FixedList::swap().
|
||||
// Internally this actually swaps the individual list elements
|
||||
@ -449,6 +465,32 @@ template<class T, unsigned Size>
|
||||
inline void Swap(FixedList<T,Size>& lhs, FixedList<T,Size>& rhs);
|
||||
|
||||
|
||||
//- Hashing for FixedList data, which uses Hasher for contiguous data and
|
||||
//- element-wise incrementally hashing otherwise.
|
||||
template<>
|
||||
template<class T, unsigned N>
|
||||
struct Hash<FixedList<T, N>>
|
||||
{
|
||||
inline unsigned operator()
|
||||
(
|
||||
const FixedList<T, N>& obj,
|
||||
unsigned seed=0
|
||||
) const
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
return Hasher(obj.cdata(), N*sizeof(T), seed);
|
||||
}
|
||||
|
||||
for (const T& val : obj)
|
||||
{
|
||||
seed = Hash<T>()(val, seed);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -25,8 +25,6 @@ License
|
||||
|
||||
#include "UList.H"
|
||||
#include "SLList.H"
|
||||
#include "contiguous.H"
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@ -570,32 +568,6 @@ inline bool Foam::FixedList<T, Size>::empty() const
|
||||
}
|
||||
|
||||
|
||||
template<class T, unsigned Size>
|
||||
template<class HashT>
|
||||
inline unsigned Foam::FixedList<T, Size>::Hash<HashT>::operator()
|
||||
(
|
||||
const FixedList<T, Size>& list,
|
||||
unsigned seed
|
||||
) const
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
// Hash directly
|
||||
return Hasher(list.v_, sizeof(list.v_), seed);
|
||||
}
|
||||
|
||||
// Hash incrementally
|
||||
unsigned val = seed;
|
||||
|
||||
for (unsigned i=0; i<Size; ++i)
|
||||
{
|
||||
val = HashT()(list[i], val);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, unsigned Size>
|
||||
|
||||
@ -344,6 +344,30 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
||||
|
||||
//- Hashing for List data, which uses Hasher for contiguous data and
|
||||
//- element-wise incrementally hashing otherwise.
|
||||
template<>
|
||||
template<class T>
|
||||
struct Hash<List<T>>
|
||||
{
|
||||
inline unsigned operator()(const UList<T>& obj, unsigned seed=0) const
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
return Hasher(obj.cdata(), obj.size()*sizeof(T), seed);
|
||||
}
|
||||
|
||||
for (const T& val : obj)
|
||||
{
|
||||
seed = Hash<T>()(val, seed);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -45,10 +45,12 @@ SourceFiles
|
||||
#include "bool.H"
|
||||
#include "label.H"
|
||||
#include "uLabel.H"
|
||||
#include "nullObject.H"
|
||||
#include "zero.H"
|
||||
#include "contiguous.H"
|
||||
#include "nullObject.H"
|
||||
#include "stdFoam.H"
|
||||
#include "Swap.H"
|
||||
#include "HashFwd.H"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
@ -529,10 +531,38 @@ public:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Other
|
||||
|
||||
//- Hashing function class for UList.
|
||||
// Can use this one (instead of the global Hash<>) for inheritance
|
||||
// in sub-classes
|
||||
template<class HashT=Foam::Hash<T>>
|
||||
struct Hash
|
||||
{
|
||||
inline unsigned operator()
|
||||
(
|
||||
const UList<T>& obj,
|
||||
unsigned seed=0
|
||||
) const
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
return Hasher(obj.cdata(), obj.size()*sizeof(T), seed);
|
||||
}
|
||||
|
||||
for (const T& val : obj)
|
||||
{
|
||||
seed = HashT()(val, seed);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Global Functions
|
||||
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
void sort(UList<T>& a);
|
||||
@ -562,6 +592,27 @@ template<class T>
|
||||
inline void Swap(UList<T>& a, UList<T>& b);
|
||||
|
||||
|
||||
//- Hashing for UList data, which uses Hasher for contiguous data and
|
||||
//- element-wise incrementally hashing otherwise.
|
||||
template<>
|
||||
template<class T>
|
||||
struct Hash<UList<T>>
|
||||
{
|
||||
inline unsigned operator()(const UList<T>& obj, unsigned seed=0) const
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
return Hasher(obj.cdata(), obj.size()*sizeof(T), seed);
|
||||
}
|
||||
for (const T& val : obj)
|
||||
{
|
||||
seed = Hash<T>()(val, seed);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -24,6 +24,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "error.H"
|
||||
#include "contiguous.H"
|
||||
#include "pTraits.H"
|
||||
#include "Swap.H"
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
// Access
|
||||
|
||||
//- Return first vertex label
|
||||
using labelPair::first;
|
||||
@ -124,7 +124,7 @@ public:
|
||||
inline edge reverseEdge() const;
|
||||
|
||||
|
||||
// Queries
|
||||
// Queries
|
||||
|
||||
//- Return the smallest point label used by the edge
|
||||
// No special handling of negative point labels.
|
||||
@ -155,7 +155,7 @@ public:
|
||||
inline label otherVertex(const label index) const;
|
||||
|
||||
|
||||
// Editing
|
||||
// Editing
|
||||
|
||||
//- 'Collapse' edge by marking duplicate point labels as '-1',
|
||||
// the lower vertex is retained.
|
||||
@ -163,7 +163,7 @@ public:
|
||||
inline label collapse();
|
||||
|
||||
|
||||
// Hash-like functions
|
||||
// Hash-like functions
|
||||
|
||||
//- Return the number of unique, valid (non -1) point labels.
|
||||
// Similar to a HashTable::size().
|
||||
@ -260,10 +260,43 @@ public:
|
||||
// - -1: identical values, but in different order
|
||||
static inline int compare(const edge& a, const edge& b);
|
||||
|
||||
|
||||
// Hashing
|
||||
|
||||
//- The (commutative) hash-value for edge
|
||||
inline unsigned hashval(unsigned seed=0) const
|
||||
{
|
||||
if (first() < second())
|
||||
{
|
||||
seed = Foam::Hash<label>()(first(), seed);
|
||||
seed = Foam::Hash<label>()(second(), seed);
|
||||
}
|
||||
else
|
||||
{
|
||||
seed = Foam::Hash<label>()(second(), seed);
|
||||
seed = Foam::Hash<label>()(first(), seed);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
|
||||
//- Hashing function class for edge (commutative)
|
||||
// Also useful for inheritance in sub-classes
|
||||
template<class HashT=Foam::Hash<label>>
|
||||
struct Hash
|
||||
{
|
||||
inline unsigned operator()(const edge& obj, unsigned seed=0) const
|
||||
{
|
||||
return obj.hashval(seed);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
||||
|
||||
// Edges are a pair of labels - thus contiguous
|
||||
template<> inline bool contiguous<edge>() {return true;}
|
||||
|
||||
|
||||
//- Return reverse of an edge
|
||||
inline edge reverse(const edge& e)
|
||||
@ -272,6 +305,19 @@ inline edge reverse(const edge& e)
|
||||
}
|
||||
|
||||
|
||||
//- Hash specialization for edge, using a commutative (incremental) hash.
|
||||
template<>
|
||||
struct Hash<edge>
|
||||
{
|
||||
inline unsigned operator()(const edge& e, unsigned seed=0) const
|
||||
{
|
||||
return e.hashval(seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * //
|
||||
|
||||
//- Compare edges for equal content, ignoring orientation
|
||||
inline bool operator==(const edge& a, const edge& b);
|
||||
|
||||
@ -279,41 +325,6 @@ inline bool operator==(const edge& a, const edge& b);
|
||||
inline bool operator!=(const edge& a, const edge& b);
|
||||
|
||||
|
||||
//- Hash specialization for hashing edges as a commutative hash value.
|
||||
// Hash incrementally.
|
||||
template<>
|
||||
inline unsigned Hash<edge>::operator()(const edge& e, unsigned seed) const
|
||||
{
|
||||
unsigned val = seed;
|
||||
|
||||
if (e.first() < e.second())
|
||||
{
|
||||
val = Hash<label>()(e.first(), val);
|
||||
val = Hash<label>()(e.second(), val);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Hash<label>()(e.second(), val);
|
||||
val = Hash<label>()(e.first(), val);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
//- Hash specialization for hashing edges as a commutative hash value.
|
||||
// Hash incrementally.
|
||||
template<>
|
||||
inline unsigned Hash<edge>::operator()(const edge& e) const
|
||||
{
|
||||
return Hash<edge>()(e, 0);
|
||||
}
|
||||
|
||||
// Edges are a pair of labels - thus contiguous
|
||||
template<>
|
||||
inline bool contiguous<edge>() {return true;}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -402,6 +402,19 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
//- Hash specialization for face
|
||||
template<>
|
||||
struct Hash<face>
|
||||
{
|
||||
inline unsigned operator()(const face& obj, unsigned seed=0) const
|
||||
{
|
||||
return Hasher(obj.cdata(), obj.size()*sizeof(label), seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- Specialization to offset faces, used in ListListOps::combineOffset
|
||||
template<>
|
||||
struct offsetOp<face>
|
||||
@ -414,27 +427,26 @@ struct offsetOp<face>
|
||||
{
|
||||
face result(x.size());
|
||||
|
||||
forAll(x, xI)
|
||||
forAll(x, i)
|
||||
{
|
||||
result[xI] = x[xI] + offset;
|
||||
result[i] = x[i] + offset;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Global operators
|
||||
inline bool operator==(const face& a, const face& b);
|
||||
inline bool operator!=(const face& a, const face& b);
|
||||
|
||||
|
||||
// Global functions
|
||||
|
||||
//- Find the longest edge on a face. Face point labels index into pts.
|
||||
// \deprecated use class method instead (APR-2017)
|
||||
label longestEdge(const face& f, const UList<point>& pts);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
|
||||
|
||||
inline bool operator==(const face& a, const face& b);
|
||||
inline bool operator!=(const face& a, const face& b);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -53,8 +53,7 @@ SourceFiles
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of friend functions and operators
|
||||
|
||||
// Forward declarations
|
||||
class face;
|
||||
class triFace;
|
||||
|
||||
@ -246,38 +245,52 @@ public:
|
||||
// - -1: same face, but different orientation
|
||||
static inline int compare(const triFace& a, const triFace& b);
|
||||
|
||||
|
||||
// Hashing
|
||||
|
||||
//- The (commutative) hash-value for triFace
|
||||
inline unsigned hashval(unsigned seed=0) const
|
||||
{
|
||||
// Fortunately we don't need this very often
|
||||
const uLabel t0((*this)[0]);
|
||||
const uLabel t1((*this)[1]);
|
||||
const uLabel t2((*this)[2]);
|
||||
|
||||
const uLabel val = (t0*t1*t2 + t0+t1+t2);
|
||||
|
||||
return Foam::Hash<uLabel>()(val, seed);
|
||||
}
|
||||
|
||||
//- Hashing function class for triFace (commutative)
|
||||
// Also useful for inheritance in sub-classes
|
||||
template<class HashT=Foam::Hash<label>>
|
||||
struct Hash
|
||||
{
|
||||
inline unsigned operator()
|
||||
(
|
||||
const triFace& obj,
|
||||
unsigned seed=0
|
||||
) const
|
||||
{
|
||||
return obj.hashval(seed);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
inline bool contiguous<triFace>() {return true;}
|
||||
|
||||
inline bool operator==(const triFace& a, const triFace& b);
|
||||
inline bool operator!=(const triFace& a, const triFace& b);
|
||||
|
||||
|
||||
//- Hash specialization for triFace as a commutative hash value.
|
||||
// Hashes incrementally.
|
||||
template<>
|
||||
inline unsigned Hash<triFace>::operator()(const triFace& t, unsigned seed) const
|
||||
{
|
||||
// Fortunately we don't need this very often
|
||||
const uLabel t0(t[0]);
|
||||
const uLabel t1(t[1]);
|
||||
const uLabel t2(t[2]);
|
||||
|
||||
const uLabel val = (t0*t1*t2 + t0+t1+t2);
|
||||
|
||||
return Hash<uLabel>()(val, seed);
|
||||
}
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<> inline bool contiguous<triFace>() {return true;}
|
||||
|
||||
//- Hash specialization for triFace as a commutative hash value.
|
||||
template<>
|
||||
inline unsigned Hash<triFace>::operator()(const triFace& t) const
|
||||
struct Hash<triFace>
|
||||
{
|
||||
return Hash<triFace>::operator()(t, 0);
|
||||
}
|
||||
inline unsigned operator()(const triFace& obj, unsigned seed=0) const
|
||||
{
|
||||
return obj.hashval(seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- Specialization to offset faces, used in ListListOps::combineOffset
|
||||
@ -290,17 +303,23 @@ struct offsetOp<triFace>
|
||||
const label offset
|
||||
) const
|
||||
{
|
||||
triFace result(x);
|
||||
triFace result;
|
||||
|
||||
forAll(x, xI)
|
||||
forAll(x, i)
|
||||
{
|
||||
result[xI] = x[xI] + offset;
|
||||
result[i] = x[i] + offset;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
|
||||
|
||||
inline bool operator==(const triFace& a, const triFace& b);
|
||||
inline bool operator!=(const triFace& a, const triFace& b);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -200,11 +200,11 @@ int Foam::processorCyclicPolyPatch::tag() const
|
||||
|
||||
if (owner())
|
||||
{
|
||||
tag_ = Hash<word>()(cycPatch.name()) % 32768u;
|
||||
tag_ = string::hash()(cycPatch.name()) % 32768u;
|
||||
}
|
||||
else
|
||||
{
|
||||
tag_ = Hash<word>()(cycPatch.neighbPatch().name()) % 32768u;
|
||||
tag_ = string::hash()(cycPatch.neighbPatch().name()) % 32768u;
|
||||
}
|
||||
|
||||
if (tag_ == Pstream::msgType() || tag_ == -1)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -82,7 +82,7 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
// Access
|
||||
|
||||
//- Return first element
|
||||
using FixedList<T, 2>::first;
|
||||
@ -100,13 +100,13 @@ public:
|
||||
inline const T& other(const T& a) const;
|
||||
|
||||
|
||||
// Queries
|
||||
// Queries
|
||||
|
||||
//- True if first() is less-than second()
|
||||
inline bool sorted() const;
|
||||
|
||||
|
||||
// Editing
|
||||
// Editing
|
||||
|
||||
//- Flip the Pair in-place.
|
||||
inline void flip();
|
||||
@ -115,7 +115,7 @@ public:
|
||||
inline void sort();
|
||||
|
||||
|
||||
// Comparison
|
||||
// Comparison
|
||||
|
||||
//- Compare Pairs
|
||||
// \return
|
||||
@ -123,6 +123,57 @@ public:
|
||||
// - +1: identical values and order used
|
||||
// - -1: identical values, but in reversed order
|
||||
static inline int compare(const Pair<T>& a, const Pair<T>& b);
|
||||
|
||||
|
||||
// Hashing
|
||||
|
||||
//- Symmetrical hashing for Pair data.
|
||||
// The lower value is hashed first.
|
||||
template<class HashT=Foam::Hash<T>>
|
||||
struct SymmHash
|
||||
{
|
||||
inline unsigned operator()
|
||||
(
|
||||
const Pair<T>& obj,
|
||||
unsigned seed=0
|
||||
) const
|
||||
{
|
||||
if (obj.first() < obj.second())
|
||||
{
|
||||
seed = HashT()(obj.first(), seed);
|
||||
seed = HashT()(obj.second(), seed);
|
||||
}
|
||||
else
|
||||
{
|
||||
seed = HashT()(obj.second(), seed);
|
||||
seed = HashT()(obj.first(), seed);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
||||
|
||||
//- Hashing for Pair data, which uses Hasher for contiguous data and
|
||||
//- element-wise incrementally hashing otherwise.
|
||||
template<>
|
||||
template<class T>
|
||||
struct Hash<Pair<T>>
|
||||
{
|
||||
inline unsigned operator()(const Pair<T>& obj, unsigned seed=0) const
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
return Hasher(obj.cdata(), sizeof(obj), seed);
|
||||
}
|
||||
|
||||
seed = Hash<T>()(obj.first(), seed);
|
||||
seed = Hash<T>()(obj.second(), seed);
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -25,7 +25,8 @@ Class
|
||||
Foam::Hash
|
||||
|
||||
Description
|
||||
Hash function class for primitives. All non-primitives used to hash
|
||||
Hash function class.
|
||||
The default definition is for primitives, non-primitives used to hash
|
||||
entries on hash tables likely need a specialized version of this class.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -36,7 +37,6 @@ Description
|
||||
#include "label.H"
|
||||
#include "uLabel.H"
|
||||
#include "Hasher.H"
|
||||
#include "pTraits.H"
|
||||
#include "fileName.H"
|
||||
#include "wordRe.H"
|
||||
|
||||
@ -44,8 +44,6 @@ Description
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
//template<class Type> struct Hash;
|
||||
//template<> struct Hash<label>;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Hash Declaration
|
||||
@ -54,134 +52,106 @@ namespace Foam
|
||||
template<class PrimitiveType>
|
||||
struct Hash
|
||||
{
|
||||
unsigned operator()(const PrimitiveType& p, unsigned seed) const
|
||||
inline unsigned operator()(const PrimitiveType& obj, unsigned seed=0) const
|
||||
{
|
||||
return Hasher(&p, sizeof(p), seed);
|
||||
return Hasher(&obj, sizeof(obj), seed);
|
||||
}
|
||||
|
||||
unsigned operator()(const PrimitiveType& p) const
|
||||
{
|
||||
return Hasher(&p, sizeof(p));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Hash specialization for hashing labels
|
||||
//- Hash specialization for label
|
||||
template<>
|
||||
struct Hash<Foam::label>
|
||||
{
|
||||
//- Incrementally hash a label.
|
||||
// This will necessarily return a different value than the
|
||||
// non-incremental version.
|
||||
unsigned operator()(const label p, unsigned seed) const
|
||||
inline unsigned operator()(const label obj, unsigned seed) const
|
||||
{
|
||||
return Hasher(&p, sizeof(label), seed);
|
||||
return Hasher(&obj, sizeof(label), seed);
|
||||
}
|
||||
|
||||
//- Return the unsigned representation of a label.
|
||||
// This helps if people have relied on the hash value corresponding to
|
||||
// the natural order.
|
||||
unsigned operator()(const label p) const
|
||||
inline unsigned operator()(const label obj) const
|
||||
{
|
||||
return p;
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- Hash specialization for hashing strings
|
||||
//- Hash specialization for string
|
||||
template<>
|
||||
struct Hash<Foam::string>
|
||||
{
|
||||
unsigned operator()(const string& p, unsigned seed) const
|
||||
inline unsigned operator()(const string& obj, unsigned seed=0) const
|
||||
{
|
||||
return string::hash()(p, seed);
|
||||
}
|
||||
unsigned operator()(const string& p) const
|
||||
{
|
||||
return string::hash()(p);
|
||||
return string::hash()(obj, seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- Hash specialization for hashing words
|
||||
//- Hash specialization for word
|
||||
template<>
|
||||
struct Hash<Foam::word>
|
||||
{
|
||||
unsigned operator()(const word& p, unsigned seed) const
|
||||
inline unsigned operator()(const word& obj, unsigned seed=0) const
|
||||
{
|
||||
return word::hash()(p, seed);
|
||||
}
|
||||
unsigned operator()(const word& p) const
|
||||
{
|
||||
return word::hash()(p);
|
||||
return string::hash()(obj, seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- Hash specialization for hashing fileNames
|
||||
//- Hash specialization for fileName
|
||||
template<>
|
||||
struct Hash<Foam::fileName>
|
||||
{
|
||||
unsigned operator()(const fileName& p, unsigned seed) const
|
||||
inline unsigned operator()(const fileName& obj, unsigned seed=0) const
|
||||
{
|
||||
return fileName::hash()(p, seed);
|
||||
}
|
||||
unsigned operator()(const fileName& p) const
|
||||
{
|
||||
return fileName::hash()(p);
|
||||
return string::hash()(obj, seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- Hash specialization for hashing wordRes
|
||||
//- Hash specialization for wordRe
|
||||
template<>
|
||||
struct Hash<Foam::wordRe>
|
||||
{
|
||||
unsigned operator()(const wordRe& p, unsigned seed) const
|
||||
inline unsigned operator()(const wordRe& obj, unsigned seed=0) const
|
||||
{
|
||||
return wordRe::hash()(p, seed);
|
||||
}
|
||||
unsigned operator()(const wordRe& p) const
|
||||
{
|
||||
return wordRe::hash()(p);
|
||||
return string::hash()(obj, seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- Hash specialization for hashing keyTypes
|
||||
//- Hash specialization for keyType
|
||||
template<>
|
||||
struct Hash<Foam::keyType>
|
||||
{
|
||||
unsigned operator()(const keyType& p, unsigned seed) const
|
||||
inline unsigned operator()(const keyType& obj, unsigned seed=0) const
|
||||
{
|
||||
return keyType::hash()(p, seed);
|
||||
}
|
||||
unsigned operator()(const keyType& p) const
|
||||
{
|
||||
return keyType::hash()(p);
|
||||
return string::hash()(obj, seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- Hash specialization for hashing pointer addresses.
|
||||
// Treat a pointer like a long.
|
||||
// This should work for both 32-bit and 64-bit pointers.
|
||||
//- Hash specialization for pointers.
|
||||
// Interpret pointer as a long (works for 32-bit and 64-bit pointers).
|
||||
template<>
|
||||
struct Hash<void*>
|
||||
{
|
||||
unsigned operator()(const void* const& p, unsigned seed) const
|
||||
inline unsigned operator()(const void* const& obj, unsigned seed) const
|
||||
{
|
||||
return Hash<long>()(long(p), seed);
|
||||
return Hash<long>()(long(obj), seed);
|
||||
}
|
||||
|
||||
unsigned operator()(const void* const& p) const
|
||||
inline unsigned operator()(const void* const& obj) const
|
||||
{
|
||||
return Hash<long>()(long(p));
|
||||
return Hash<long>()(long(obj));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
46
src/OpenFOAM/primitives/hashes/Hash/HashFwd.H
Normal file
46
src/OpenFOAM/primitives/hashes/Hash/HashFwd.H
Normal file
@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Description
|
||||
Forward definition for Hash function class and the definition for
|
||||
the Hasher function.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef HashFwd_H
|
||||
#define HashFwd_H
|
||||
|
||||
#include "Hasher.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
template<class T> struct Hash;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -53,11 +53,21 @@ namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Bob Jenkins's 96-bit mixer hashing function (lookup3)
|
||||
// \param[in] data - a character stream
|
||||
// \param[in] len - the number of bytes
|
||||
// \param[in] seed - the previous hash, or an arbitrary value
|
||||
unsigned Hasher(const void* data, size_t len, unsigned seed = 0);
|
||||
//- Bob Jenkins's 96-bit mixer hashing function (lookup3)
|
||||
// \param[in] data - a character stream
|
||||
// \param[in] len - the number of bytes
|
||||
// \param[in] seed - the previous hash, or an arbitrary value
|
||||
unsigned Hasher(const void* data, size_t len, unsigned seed = 0);
|
||||
|
||||
|
||||
//- Hashing of bit-wise internal content of given data object.
|
||||
// For primitives and simple collections of primitives this is reasonable,
|
||||
// but ill-advised for more complex data structures.
|
||||
template<class T>
|
||||
inline unsigned HasherT(const T& obj, unsigned seed = 0)
|
||||
{
|
||||
return Hasher(&obj, sizeof(obj), seed);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -26,9 +26,8 @@ License
|
||||
#include "cuttingPlane.H"
|
||||
#include "fvMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "linePointRef.H"
|
||||
#include "meshTools.H"
|
||||
#include "EdgeMap.H"
|
||||
#include "edgeHashes.H"
|
||||
#include "HashOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
@ -80,29 +79,8 @@ namespace Foam
|
||||
}
|
||||
|
||||
|
||||
//- Hash specialization for labelList. Hash incrementally.
|
||||
template<>
|
||||
inline unsigned Hash<labelList>::operator()
|
||||
(
|
||||
const labelList& list,
|
||||
unsigned seed
|
||||
) const
|
||||
{
|
||||
return Hasher(list.cdata(), list.size()*sizeof(label), seed);
|
||||
}
|
||||
|
||||
//- Hash specialization for labelList
|
||||
template<>
|
||||
inline unsigned Hash<labelList>::operator()
|
||||
(
|
||||
const labelList& list
|
||||
) const
|
||||
{
|
||||
return Hash<labelList>()(list, 0);
|
||||
}
|
||||
|
||||
//- For hashing face point labels, which are pre-sorted.
|
||||
typedef HashSet<labelList, Hash<labelList>> labelListHashSet;
|
||||
typedef HashSet<labelList, labelList::Hash<>> labelListHashSet;
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -354,6 +332,7 @@ void Foam::cuttingPlane::walkCellCuts
|
||||
{
|
||||
edge e(f.faceEdge(fp));
|
||||
|
||||
// Action #1: detect edge intersection and orient edge
|
||||
if (!intersectEdgeOrient(sides, e))
|
||||
{
|
||||
continue;
|
||||
@ -388,6 +367,7 @@ void Foam::cuttingPlane::walkCellCuts
|
||||
const point& p0 = points[e[0]];
|
||||
const point& p1 = points[e[1]];
|
||||
|
||||
// Action #2: edge cut alpha
|
||||
const scalar alpha =
|
||||
this->lineIntersect(linePointRef(p0, p1));
|
||||
|
||||
@ -540,6 +520,7 @@ void Foam::cuttingPlane::walkCellCuts
|
||||
|
||||
face f(localFaceLoop);
|
||||
|
||||
// Action #3: orient face
|
||||
// Orient face to point in the same direction as the plane normal
|
||||
if ((f.areaNormal(dynCutPoints) & this->normal()) < 0)
|
||||
{
|
||||
|
||||
@ -40,7 +40,6 @@ SourceFiles
|
||||
#include "edge.H"
|
||||
#include "face.H"
|
||||
#include "triPointRef.H"
|
||||
#include "linePointRef.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
Reference in New Issue
Block a user