mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Switched from old hashing functions to use Bob Jenkins' hash routine
- If the underlying type is contiguous, FixedList hashes its storage directly. - Drop labelPairHash (non-commutative) from fvMeshDistribute since FixedList::Hash does the right thing anyhow. - Hash<edge> specialization is commutative, without multiplication. - Hash<triFace> specialization kept multiplication (but now uLabel). There's not much point optimizing it, since it's not used much anyhow. Misc. changes - added StaticAssert to NamedEnum.H - label.H / uLabel.H : define FOAM_LABEL_MAX, FOAM_ULABEL_MAX with the values finally used for the storage. These can be useful for pre-processor checks elsewhere (although I stopped needing them in the meantime).
This commit is contained in:
@ -56,6 +56,12 @@ int main(int argc, char *argv[])
|
|||||||
Info<< "list:" << list
|
Info<< "list:" << list
|
||||||
<< " hash:" << FixedList<label, 4>::Hash<>()(list) << endl;
|
<< " hash:" << FixedList<label, 4>::Hash<>()(list) << endl;
|
||||||
|
|
||||||
|
Info<< "FixedList<label, ..> is contiguous, "
|
||||||
|
"thus hashing function is irrelevant: with string::hash" << endl;
|
||||||
|
|
||||||
|
Info<< "list:" << list
|
||||||
|
<< " hash:" << FixedList<label, 4>::Hash<string::hash>()(list) << endl;
|
||||||
|
|
||||||
label a[4] = {0, 1, 2, 3};
|
label a[4] = {0, 1, 2, 3};
|
||||||
FixedList<label, 4> list2(a);
|
FixedList<label, 4> list2(a);
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ Description
|
|||||||
#include "labelList.H"
|
#include "labelList.H"
|
||||||
#include "labelPair.H"
|
#include "labelPair.H"
|
||||||
|
|
||||||
#include "Hashing.H"
|
#include "Hash.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -65,64 +65,40 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
forAll(lst, i)
|
forAll(lst, i)
|
||||||
{
|
{
|
||||||
unsigned hash1 = Hashing::jenkins(lst[i]);
|
unsigned hash1 = string::hash()(lst[i]);
|
||||||
unsigned hash2 = string::hash()(lst[i]);
|
|
||||||
|
|
||||||
Info<< hex << hash1
|
Info<< hex << hash1 << ": " << lst[i] << endl;
|
||||||
<< " (prev " << hash2 << ")"
|
|
||||||
<< ": " << lst[i] << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (listType == "labelList")
|
else if (listType == "labelList")
|
||||||
{
|
{
|
||||||
Info<<"contiguous = " << contiguous<label>() << " "
|
Info<<"contiguous = " << contiguous<label>() << endl << endl;
|
||||||
<< "sizeof(label) " << unsigned(sizeof(label)) << endl << endl;
|
|
||||||
|
|
||||||
labelList lst(is);
|
labelList lst(is);
|
||||||
|
|
||||||
unsigned hash4 = 0;
|
|
||||||
|
|
||||||
forAll(lst, i)
|
forAll(lst, i)
|
||||||
{
|
{
|
||||||
unsigned hash1 = Hashing::intHash(lst[i]);
|
// direct value
|
||||||
|
unsigned hash1 = Hash<label>()(lst[i]);
|
||||||
|
|
||||||
unsigned hash2 = Hashing::jenkins
|
// hashed byte-wise
|
||||||
(
|
unsigned hash2 = Hash<label>()(lst[i], 0);
|
||||||
reinterpret_cast<const char*>(&lst[i]),
|
|
||||||
sizeof(label)
|
|
||||||
);
|
|
||||||
|
|
||||||
unsigned hash3 = Hashing::jenkins
|
|
||||||
(
|
|
||||||
reinterpret_cast<const unsigned*>(&lst[i]),
|
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
// incremental
|
|
||||||
hash4 = Hashing::jenkins
|
|
||||||
(
|
|
||||||
reinterpret_cast<const char*>(&lst[i]),
|
|
||||||
sizeof(label),
|
|
||||||
hash4
|
|
||||||
);
|
|
||||||
|
|
||||||
Info<< hex << hash1
|
Info<< hex << hash1
|
||||||
<< " (alt: " << hash2 << ")"
|
<< " (seeded: " << hash2 << ")"
|
||||||
<< " (alt: " << hash3 << ")"
|
|
||||||
<< " (incr: " << hash4 << ")"
|
|
||||||
<< ": " << dec << lst[i] << endl;
|
<< ": " << dec << lst[i] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contiguous<label>())
|
if (contiguous<label>())
|
||||||
{
|
{
|
||||||
unsigned hash1 = Hashing::jenkins
|
unsigned hash3 = Hasher
|
||||||
(
|
(
|
||||||
lst.cdata(),
|
lst.cdata(),
|
||||||
lst.size() * sizeof(label)
|
lst.size() * sizeof(label)
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<<"contiguous hashed value " << hex << hash1 << endl;
|
Info<<"contiguous hashed value " << hex << hash3 << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (listType == "labelListList")
|
else if (listType == "labelListList")
|
||||||
@ -131,9 +107,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
forAll(lst, i)
|
forAll(lst, i)
|
||||||
{
|
{
|
||||||
unsigned hash1 = Hashing::jenkins
|
unsigned hash1 = Hasher
|
||||||
(
|
(
|
||||||
reinterpret_cast<const char*>(lst[i].cdata()),
|
lst[i].cdata(),
|
||||||
lst[i].size() * sizeof(label)
|
lst[i].size() * sizeof(label)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// code taken more-or-less from Paul Hsieh's tests
|
// code taken more-or-less from Paul Hsieh's tests
|
||||||
|
|
||||||
#include "Hashing.H"
|
#include "Hasher.H"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -692,7 +692,7 @@ uint32_t hashLookup3Orig (const char * k, int length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t hashLookup3 (const char * k, int length) {
|
uint32_t hashLookup3 (const char * k, int length) {
|
||||||
return Foam::Hashing::jenkins(k, length);
|
return Foam::Hasher(k, length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@ $(strings)/fileName/fileNameIO.C
|
|||||||
$(strings)/keyType/keyTypeIO.C
|
$(strings)/keyType/keyTypeIO.C
|
||||||
$(strings)/wordRe/wordReIO.C
|
$(strings)/wordRe/wordReIO.C
|
||||||
|
|
||||||
primitives/hashes/Hashing/Hashing.C
|
primitives/hashes/Hasher/Hasher.C
|
||||||
|
|
||||||
sha1 = primitives/hashes/SHA1
|
sha1 = primitives/hashes/SHA1
|
||||||
$(sha1)/SHA1.C
|
$(sha1)/SHA1.C
|
||||||
|
|||||||
@ -82,8 +82,8 @@ class FixedList
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Hashing function class
|
//- Hashing function class.
|
||||||
// Rotating hash from http://burtleburtle.net/bob/hash/doobs.html
|
// Use Hasher directly for contiguous data. Otherwise hash incrementally.
|
||||||
template< class HashT=Hash<T> >
|
template< class HashT=Hash<T> >
|
||||||
class Hash
|
class Hash
|
||||||
{
|
{
|
||||||
@ -91,7 +91,11 @@ public:
|
|||||||
Hash()
|
Hash()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline unsigned operator()(const FixedList<T, Size>&) const;
|
inline unsigned operator()
|
||||||
|
(
|
||||||
|
const FixedList<T, Size>&,
|
||||||
|
unsigned seed = 0
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Static Member Functions
|
// Static Member Functions
|
||||||
|
|||||||
@ -403,25 +403,31 @@ inline bool Foam::FixedList<T, Size>::empty() const
|
|||||||
|
|
||||||
|
|
||||||
#ifndef __CINT__
|
#ifndef __CINT__
|
||||||
|
|
||||||
// Rotating Hash
|
|
||||||
template<class T, unsigned Size>
|
template<class T, unsigned Size>
|
||||||
template<class HashT>
|
template<class HashT>
|
||||||
inline unsigned Foam::FixedList<T, Size>::Hash<HashT>::operator()
|
inline unsigned Foam::FixedList<T, Size>::Hash<HashT>::operator()
|
||||||
(
|
(
|
||||||
const FixedList<T, Size>& lst
|
const FixedList<T, Size>& lst,
|
||||||
|
unsigned seed
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
static const unsigned farbit(8*sizeof(label)-4);
|
if (contiguous<T>())
|
||||||
|
|
||||||
unsigned val = Size;
|
|
||||||
|
|
||||||
for (register unsigned i=0; i<Size; i++)
|
|
||||||
{
|
{
|
||||||
val = (val << 4) ^ (val >> farbit) ^ HashT()(lst[i]);
|
// hash directly
|
||||||
|
return Hasher(lst.v_, sizeof(lst.v_), seed);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// hash incrementally
|
||||||
|
unsigned val = seed;
|
||||||
|
|
||||||
return val;
|
for (register unsigned i=0; i<Size; i++)
|
||||||
|
{
|
||||||
|
val = HashT()(lst[i], val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __CINT__
|
#endif // __CINT__
|
||||||
|
|||||||
@ -37,6 +37,7 @@ SourceFiles
|
|||||||
#define NamedEnum_H
|
#define NamedEnum_H
|
||||||
|
|
||||||
#include "HashTable.H"
|
#include "HashTable.H"
|
||||||
|
#include "StaticAssert.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -52,6 +53,9 @@ class NamedEnum
|
|||||||
:
|
:
|
||||||
public HashTable<int>
|
public HashTable<int>
|
||||||
{
|
{
|
||||||
|
//- nEnum must be positive (non-zero)
|
||||||
|
StaticAssert(nEnum > 0);
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
@ -99,7 +103,7 @@ public:
|
|||||||
return Enum(HashTable<int>::operator[](name));
|
return Enum(HashTable<int>::operator[](name));
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Return the name or the given enumeration element
|
//- Return the name of the given enumeration element
|
||||||
const char* operator[](const Enum e) const
|
const char* operator[](const Enum e) const
|
||||||
{
|
{
|
||||||
return names[e];
|
return names[e];
|
||||||
|
|||||||
@ -133,14 +133,37 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//- Hash specialization for hashing edges
|
//- Hash specialization for hashing edges - a commutative hash value.
|
||||||
// Simple commutative hash.
|
// Hash incrementally.
|
||||||
|
template<>
|
||||||
|
inline unsigned Hash<edge>::operator()(const edge& e, unsigned seed) const
|
||||||
|
{
|
||||||
|
unsigned val = seed;
|
||||||
|
|
||||||
|
if (e[0] < e[1])
|
||||||
|
{
|
||||||
|
val = Hash<label>()(e[0], val);
|
||||||
|
val = Hash<label>()(e[1], val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val = Hash<label>()(e[1], val);
|
||||||
|
val = Hash<label>()(e[0], val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Hash specialization for hashing edges - a commutative hash value.
|
||||||
|
// Hash incrementally.
|
||||||
template<>
|
template<>
|
||||||
inline unsigned Hash<edge>::operator()(const edge& e) const
|
inline unsigned Hash<edge>::operator()(const edge& e) const
|
||||||
{
|
{
|
||||||
return (e[0]*e[1] + e[0]+e[1]);
|
return Hash<edge>()(e, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline bool contiguous<edge>() {return true;}
|
inline bool contiguous<edge>() {return true;}
|
||||||
|
|
||||||
|
|||||||
@ -164,14 +164,31 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//- Hash specialization for hashing triFace
|
//- Hash specialization for hashing triFace - a commutative hash value.
|
||||||
// Simple commutative hash.
|
// Hash 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Hash specialization for hashing triFace - a commutative hash value.
|
||||||
|
// Hash incrementally.
|
||||||
template<>
|
template<>
|
||||||
inline unsigned Hash<triFace>::operator()(const triFace& t) const
|
inline unsigned Hash<triFace>::operator()(const triFace& t) const
|
||||||
{
|
{
|
||||||
return (t[0]*t[1]*t[2] + t[0]+t[1]+t[2]);
|
return Hash<triFace>::operator()(t, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline bool contiguous<triFace>() {return true;}
|
inline bool contiguous<triFace>() {return true;}
|
||||||
|
|
||||||
|
|||||||
@ -133,7 +133,7 @@ inline Foam::pointField Foam::triFace::points(const pointField& points) const
|
|||||||
|
|
||||||
inline Foam::face Foam::triFace::triFaceFace() const
|
inline Foam::face Foam::triFace::triFaceFace() const
|
||||||
{
|
{
|
||||||
face f(3);
|
Foam::face f(3);
|
||||||
|
|
||||||
f[0] = operator[](0);
|
f[0] = operator[](0);
|
||||||
f[1] = operator[](1);
|
f[1] = operator[](1);
|
||||||
|
|||||||
@ -59,7 +59,7 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Null constructor for lists
|
//- Null constructor
|
||||||
inline Pair()
|
inline Pair()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -135,6 +135,27 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- compare Pairs
|
||||||
|
// - 0: different
|
||||||
|
// - +1: identical
|
||||||
|
// - -1: same pair, but reversed order
|
||||||
|
static inline int compare(const Pair<Type>& a, const Pair<Type>& b)
|
||||||
|
{
|
||||||
|
if (a[0] == b[0] && a[1] == b[1])
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (a[0] == b[1] && a[1] == b[0])
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Friend Operators
|
// Friend Operators
|
||||||
|
|
||||||
friend bool operator==(const Pair<Type>& a, const Pair<Type>& b)
|
friend bool operator==(const Pair<Type>& a, const Pair<Type>& b)
|
||||||
|
|||||||
@ -34,8 +34,8 @@ namespace Foam
|
|||||||
const char* const pTraits<Scalar>::typeName = "scalar";
|
const char* const pTraits<Scalar>::typeName = "scalar";
|
||||||
const Scalar pTraits<Scalar>::zero = 0.0;
|
const Scalar pTraits<Scalar>::zero = 0.0;
|
||||||
const Scalar pTraits<Scalar>::one = 1.0;
|
const Scalar pTraits<Scalar>::one = 1.0;
|
||||||
const Scalar pTraits<Scalar>::max = ScalarVGREAT;
|
|
||||||
const Scalar pTraits<Scalar>::min = -ScalarVGREAT;
|
const Scalar pTraits<Scalar>::min = -ScalarVGREAT;
|
||||||
|
const Scalar pTraits<Scalar>::max = ScalarVGREAT;
|
||||||
|
|
||||||
const char* pTraits<Scalar>::componentNames[] = { "x" };
|
const char* pTraits<Scalar>::componentNames[] = { "x" };
|
||||||
|
|
||||||
@ -47,11 +47,11 @@ pTraits<Scalar>::pTraits(Istream& is)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
word name(const Scalar s)
|
word name(const Scalar val)
|
||||||
{
|
{
|
||||||
std::ostringstream osBuffer;
|
std::ostringstream buf;
|
||||||
osBuffer << s;
|
buf << val;
|
||||||
return osBuffer.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ Description
|
|||||||
Foam::Istream& Foam::operator>>(Istream& is, char& c)
|
Foam::Istream& Foam::operator>>(Istream& is, char& c)
|
||||||
{
|
{
|
||||||
is.read(c);
|
is.read(c);
|
||||||
is.check("Istream& operator>>(Istream& is, char& c)");
|
is.check("Istream& operator>>(Istream&, char&)");
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ Class
|
|||||||
|
|
||||||
Description
|
Description
|
||||||
Hash function class for primitives. All non-primitives used to hash
|
Hash function class for primitives. All non-primitives used to hash
|
||||||
entries on hash tables need a specialized version of this class.
|
entries on hash tables likely need a specialized version of this class.
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -36,6 +36,7 @@ Description
|
|||||||
|
|
||||||
#include "label.H"
|
#include "label.H"
|
||||||
#include "uLabel.H"
|
#include "uLabel.H"
|
||||||
|
#include "Hasher.H"
|
||||||
#include "pTraits.H"
|
#include "pTraits.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -50,15 +51,19 @@ namespace Foam
|
|||||||
template<class PrimitiveType>
|
template<class PrimitiveType>
|
||||||
class Hash
|
class Hash
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Hash()
|
Hash()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
unsigned operator()(const PrimitiveType& p, unsigned seed) const
|
||||||
|
{
|
||||||
|
return Hasher(&p, sizeof(p), seed);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned operator()(const PrimitiveType& p) const
|
unsigned operator()(const PrimitiveType& p) const
|
||||||
{
|
{
|
||||||
return unsigned(p);
|
return Hasher(&p, sizeof(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -66,19 +71,53 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
//- Hash specialization for hashing pointer addresses
|
//- Hash specialization for hashing pointer addresses.
|
||||||
|
// Treat a pointer like a long.
|
||||||
|
// This should work for both 32-bit and 64-bit pointers.
|
||||||
template<>
|
template<>
|
||||||
class Hash<void*>
|
class Hash<void*>
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Hash()
|
Hash()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
unsigned operator()(const void* const& p, unsigned seed) const
|
||||||
|
{
|
||||||
|
return Hash<long>()(long(p), seed);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned operator()(const void* const& p) const
|
unsigned operator()(const void* const& p) const
|
||||||
{
|
{
|
||||||
return long(p);
|
return Hash<long>()(long(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//- Hash specialization for hashing labels
|
||||||
|
template<>
|
||||||
|
class Hash<Foam::label>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Hash()
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Incrementally hash a label.
|
||||||
|
// This will necessarily return a different value than the
|
||||||
|
// non-incremental version.
|
||||||
|
unsigned operator()(const label& p, unsigned seed) const
|
||||||
|
{
|
||||||
|
return Hasher(&p, 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
|
||||||
|
{
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -26,14 +26,16 @@ Description
|
|||||||
Hashing functions, mostly from Bob Jenkins
|
Hashing functions, mostly from Bob Jenkins
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "Hashing.H"
|
#include "Hasher.H"
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#if defined (__GLIBC__)
|
#if defined (__GLIBC__)
|
||||||
# include <endian.h>
|
# include <endian.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Left-rotate a 32-bit value and carry by nBits
|
||||||
|
#define bitRotateLeft(x, nBits) (((x) << (nBits)) | ((x) >> (32 - (nBits))))
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// lookup3.c, by Bob Jenkins, May 2006, Public Domain.
|
// lookup3.c, by Bob Jenkins, May 2006, Public Domain.
|
||||||
//
|
//
|
||||||
@ -68,7 +70,6 @@ Description
|
|||||||
// on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
// on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// mix -- mix 3 32-bit values reversibly.
|
// mix -- mix 3 32-bit values reversibly.
|
||||||
//
|
//
|
||||||
@ -112,6 +113,17 @@ Description
|
|||||||
// rotates.
|
// rotates.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define bitMixer(a, b, c) \
|
||||||
|
{ \
|
||||||
|
a -= c; a ^= bitRotateLeft(c, 4); c += b; \
|
||||||
|
b -= a; b ^= bitRotateLeft(a, 6); a += c; \
|
||||||
|
c -= b; c ^= bitRotateLeft(b, 8); b += a; \
|
||||||
|
a -= c; a ^= bitRotateLeft(c,16); c += b; \
|
||||||
|
b -= a; b ^= bitRotateLeft(a,19); a += c; \
|
||||||
|
c -= b; c ^= bitRotateLeft(b, 4); b += a; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// final -- final mixing of 3 32-bit values (a,b,c) into c
|
// final -- final mixing of 3 32-bit values (a,b,c) into c
|
||||||
//
|
//
|
||||||
@ -136,6 +148,18 @@ Description
|
|||||||
// 11 8 15 26 3 22 24
|
// 11 8 15 26 3 22 24
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define bitMixerFinal(a, b, c) \
|
||||||
|
{ \
|
||||||
|
c ^= b; c -= bitRotateLeft(b, 14); \
|
||||||
|
a ^= c; a -= bitRotateLeft(c, 11); \
|
||||||
|
b ^= a; b -= bitRotateLeft(a, 25); \
|
||||||
|
c ^= b; c -= bitRotateLeft(b, 16); \
|
||||||
|
a ^= c; a -= bitRotateLeft(c, 4); \
|
||||||
|
b ^= a; b -= bitRotateLeft(a, 14); \
|
||||||
|
c ^= b; c -= bitRotateLeft(b, 24); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -165,11 +189,11 @@ Description
|
|||||||
|
|
||||||
//- specialized little-endian code
|
//- specialized little-endian code
|
||||||
#if !defined (__BYTE_ORDER) || (__BYTE_ORDER == __LITTLE_ENDIAN)
|
#if !defined (__BYTE_ORDER) || (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||||
static uint32_t jenkins_hashlittle
|
static unsigned jenkins_hashlittle
|
||||||
(
|
(
|
||||||
const void *key,
|
const void *key,
|
||||||
size_t length,
|
size_t length,
|
||||||
uint32_t initval
|
unsigned initval
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint32_t a, b, c;
|
uint32_t a, b, c;
|
||||||
@ -343,11 +367,11 @@ static uint32_t jenkins_hashlittle
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// specialized big-endian code
|
// specialized big-endian code
|
||||||
#if !defined (__BYTE_ORDER) || (__BYTE_ORDER == __BIG_ENDIAN)
|
#if !defined (__BYTE_ORDER) || (__BYTE_ORDER == __BIG_ENDIAN)
|
||||||
static uint32_t jenkins_hashbig
|
static unsigned jenkins_hashbig
|
||||||
(
|
(
|
||||||
const void *key,
|
const void *key,
|
||||||
size_t length,
|
size_t length,
|
||||||
uint32_t initval
|
unsigned initval
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint32_t a, b, c;
|
uint32_t a, b, c;
|
||||||
@ -447,6 +471,37 @@ static uint32_t jenkins_hashbig
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Functions * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Functions * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
unsigned Foam::Hasher
|
||||||
|
(
|
||||||
|
const void *key,
|
||||||
|
size_t length,
|
||||||
|
unsigned initval
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#ifdef __BYTE_ORDER
|
||||||
|
# if (__BYTE_ORDER == __BIG_ENDIAN)
|
||||||
|
return jenkins_hashbig(key, length, initval);
|
||||||
|
# else
|
||||||
|
return jenkins_hashlittle(key, length, initval);
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
// endian-ness not known at compile-time: runtime endian test
|
||||||
|
const short endianTest = 0x0100;
|
||||||
|
|
||||||
|
// yields 0x01 for big endian
|
||||||
|
if (*(reinterpret_cast<const char *>(&endianTest)))
|
||||||
|
{
|
||||||
|
return jenkins_hashbig(key, length, initval);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return jenkins_hashlittle(key, length, initval);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// This works on all machines. To be useful, it requires
|
// This works on all machines. To be useful, it requires
|
||||||
// -- that the key be an array of uint32_t's, and
|
// -- that the key be an array of uint32_t's, and
|
||||||
@ -458,11 +513,11 @@ static uint32_t jenkins_hashbig
|
|||||||
// bytes. hashlittle() is more complicated than hashword() only because
|
// bytes. hashlittle() is more complicated than hashword() only because
|
||||||
// hashlittle() has to dance around fitting the key bytes into registers.
|
// hashlittle() has to dance around fitting the key bytes into registers.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
uint32_t Foam::Hashing::jenkins
|
unsigned Foam::HasherSingle
|
||||||
(
|
(
|
||||||
const uint32_t *k,
|
const uint32_t *k,
|
||||||
size_t length,
|
size_t length,
|
||||||
uint32_t seed
|
unsigned seed
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint32_t a, b, c;
|
uint32_t a, b, c;
|
||||||
@ -502,12 +557,12 @@ uint32_t Foam::Hashing::jenkins
|
|||||||
// both be initialized with seeds. If you pass in (*pb)==0, the output
|
// both be initialized with seeds. If you pass in (*pb)==0, the output
|
||||||
// (*pc) will be the same as the return value from hashword().
|
// (*pc) will be the same as the return value from hashword().
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
uint32_t Foam::Hashing::jenkinsTwin
|
unsigned Foam::HasherDual
|
||||||
(
|
(
|
||||||
const uint32_t *k,
|
const uint32_t *k,
|
||||||
size_t length,
|
size_t length,
|
||||||
uint32_t& hash1, // IN: seed OUT: primary hash value
|
unsigned& hash1, // IN: seed OUT: primary hash value
|
||||||
uint32_t& hash2 // IN: more seed OUT: secondary hash value
|
unsigned& hash2 // IN: more seed OUT: secondary hash value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint32_t a, b, c;
|
uint32_t a, b, c;
|
||||||
@ -547,35 +602,4 @@ uint32_t Foam::Hashing::jenkinsTwin
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t Foam::Hashing::jenkins
|
|
||||||
(
|
|
||||||
const void *key,
|
|
||||||
size_t length,
|
|
||||||
uint32_t initval
|
|
||||||
)
|
|
||||||
{
|
|
||||||
#ifdef __BYTE_ORDER
|
|
||||||
# if (__BYTE_ORDER == __BIG_ENDIAN)
|
|
||||||
return jenkins_hashbig(key, length, initval);
|
|
||||||
# else
|
|
||||||
return jenkins_hashlittle(key, length, initval);
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
// endian-ness not known at compile-time: runtime endian test
|
|
||||||
const short endianTest = 0x0100;
|
|
||||||
|
|
||||||
// yields 0x01 for big endian
|
|
||||||
if (*(reinterpret_cast<const char *>(&endianTest)))
|
|
||||||
{
|
|
||||||
return jenkins_hashbig(key, length, initval);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return jenkins_hashlittle(key, length, initval);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
93
src/OpenFOAM/primitives/hashes/Hasher/Hasher.H
Normal file
93
src/OpenFOAM/primitives/hashes/Hasher/Hasher.H
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2009 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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Namespace
|
||||||
|
Foam::Hashing
|
||||||
|
|
||||||
|
Description
|
||||||
|
Misc. hashing functions, mostly from Bob Jenkins.
|
||||||
|
|
||||||
|
The Jenkins hashing function(s) is similar in speed to Paul Hsieh's
|
||||||
|
SuperFast hash, but is public domain, supports incremental hashing
|
||||||
|
and has been reported to have better characteristics.
|
||||||
|
It is also what postgresql seems to be using.
|
||||||
|
|
||||||
|
SeeAlso
|
||||||
|
http://burtleburtle.net/bob/c/lookup3.c
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
Hasher.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Hasher_H
|
||||||
|
#define Hasher_H
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <stdint.h> // C++0x uses <cstdint>
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
//- An optimized version of Hasher
|
||||||
|
// @param[in] data - an array of uint32_t values
|
||||||
|
// @param[in] len - the number of values (not bytes)
|
||||||
|
// @param[in] seed - the previous hash, or an arbitrary value
|
||||||
|
unsigned HasherSingle(const uint32_t*, size_t length, unsigned seed = 0);
|
||||||
|
|
||||||
|
//- An optimized version of Hasher, returning dual hash values
|
||||||
|
// @param[in] data - an array of uint32_t values
|
||||||
|
// @param[in] len - the number of values (not bytes)
|
||||||
|
// @param[in] hash1 - the previous hash, or an arbitrary value
|
||||||
|
// on output, the primary hash value
|
||||||
|
// @param[in] hash1 - the previous hash, or an arbitrary value
|
||||||
|
// on output, the secondary hash value
|
||||||
|
unsigned HasherDual
|
||||||
|
(
|
||||||
|
const uint32_t*,
|
||||||
|
size_t len,
|
||||||
|
unsigned& hash1,
|
||||||
|
unsigned& hash2
|
||||||
|
);
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,321 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2009 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Namespace
|
|
||||||
Foam::Hashing
|
|
||||||
|
|
||||||
Description
|
|
||||||
Misc. hashing functions, mostly from Bob Jenkins.
|
|
||||||
|
|
||||||
The Jenkins hashing function(s) is similar in speed to Paul Hsieh's
|
|
||||||
SuperFast hash, but is public domain, supports incremental hashing
|
|
||||||
and has been reported to have better characteristics.
|
|
||||||
It is also what postgresql seems to be using.
|
|
||||||
|
|
||||||
SeeAlso
|
|
||||||
http://burtleburtle.net/bob/c/lookup3.c
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
Hashing.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef Hashing_H
|
|
||||||
#define Hashing_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <climits>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <stdint.h> // C++0x uses <cstdint>
|
|
||||||
|
|
||||||
#include "label.H"
|
|
||||||
#include "uLabel.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Macro defines
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @def bitRotateLeft(val, nBits)
|
|
||||||
* Left-rotate a 32-bit value and carry by nBits
|
|
||||||
*/
|
|
||||||
#define bitRotateLeft(x, nBits) (((x) << (nBits)) | ((x) >> (32 - (nBits))))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @def bitMixer(a, b, c)
|
|
||||||
* Mix three 32-bit values reversibly.
|
|
||||||
*/
|
|
||||||
#define bitMixer(a, b, c) \
|
|
||||||
{ \
|
|
||||||
a -= c; a ^= bitRotateLeft(c, 4); c += b; \
|
|
||||||
b -= a; b ^= bitRotateLeft(a, 6); a += c; \
|
|
||||||
c -= b; c ^= bitRotateLeft(b, 8); b += a; \
|
|
||||||
a -= c; a ^= bitRotateLeft(c,16); c += b; \
|
|
||||||
b -= a; b ^= bitRotateLeft(a,19); a += c; \
|
|
||||||
c -= b; c ^= bitRotateLeft(b, 4); b += a; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @def bitMixerFinal(a, b, c)
|
|
||||||
* Final mixing of three 32-bit values (a,b,c) into c
|
|
||||||
*/
|
|
||||||
#define bitMixerFinal(a, b, c) \
|
|
||||||
{ \
|
|
||||||
c ^= b; c -= bitRotateLeft(b, 14); \
|
|
||||||
a ^= c; a -= bitRotateLeft(c, 11); \
|
|
||||||
b ^= a; b -= bitRotateLeft(a, 25); \
|
|
||||||
c ^= b; c -= bitRotateLeft(b, 16); \
|
|
||||||
a ^= c; a -= bitRotateLeft(c, 4); \
|
|
||||||
b ^= a; b -= bitRotateLeft(a, 14); \
|
|
||||||
c ^= b; c -= bitRotateLeft(b, 24); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace Hashing
|
|
||||||
{
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
//- Bob Jenkins's 96-bit mixer hashing function (lookup3)
|
|
||||||
// @param[in] data - an array of uint32_t values
|
|
||||||
// @param[in] len - the number of values (not bytes)
|
|
||||||
// @param[in] seed - the previous hash, or an arbitrary value
|
|
||||||
uint32_t jenkins(const uint32_t*, size_t length, uint32_t seed = 0);
|
|
||||||
|
|
||||||
//- Bob Jenkins's 96-bit mixer hashing function returning twin hash values
|
|
||||||
// @param[in] data - an array of uint32_t values
|
|
||||||
// @param[in] len - the number of values (not bytes)
|
|
||||||
// @param[in] hash1 - the previous hash, or an arbitrary value
|
|
||||||
// on output, the primary hash value
|
|
||||||
// @param[in] hash1 - the previous hash, or an arbitrary value
|
|
||||||
// on output, the secondary hash value
|
|
||||||
uint32_t jenkinsTwin
|
|
||||||
(
|
|
||||||
const uint32_t*,
|
|
||||||
size_t len,
|
|
||||||
uint32_t& hash1,
|
|
||||||
uint32_t& hash2
|
|
||||||
);
|
|
||||||
|
|
||||||
//- 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
|
|
||||||
uint32_t jenkins(const void* data, size_t len, uint32_t seed = 0);
|
|
||||||
|
|
||||||
//- Hashing a C++ string with Jenkins' 96-bit mixer
|
|
||||||
inline uint32_t jenkins(const std::string& str, uint32_t seed = 0)
|
|
||||||
{
|
|
||||||
return jenkins(str.data(), str.size(), seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Hash an unsigned long like two 32bit values
|
|
||||||
inline uint32_t jenkins(const unsigned long& val)
|
|
||||||
{
|
|
||||||
uint32_t a = val >> 32;
|
|
||||||
uint32_t b = val & 0xFFFFFFFF;
|
|
||||||
uint32_t c = 0;
|
|
||||||
|
|
||||||
bitMixerFinal(a,b,c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Hash a (64-bit) pointer like any long
|
|
||||||
// Treats bits as zero if the pointer is actually 32bit
|
|
||||||
inline uint32_t pointerHash(const void* const& p)
|
|
||||||
{
|
|
||||||
return jenkins(long(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UINT_MAX > WANTEDURANGE
|
|
||||||
|
|
||||||
//- Hash a uLabel
|
|
||||||
inline unsigned intHash(const uLabel& val1)
|
|
||||||
{
|
|
||||||
uint32_t a = val1;
|
|
||||||
uint32_t b = 0;
|
|
||||||
uint32_t c = 0;
|
|
||||||
|
|
||||||
bitMixerFinal(a,b,c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Hash a uLabel pair
|
|
||||||
inline unsigned intHash
|
|
||||||
(
|
|
||||||
const uLabel& val1,
|
|
||||||
const uLabel& val2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint32_t a = val1;
|
|
||||||
uint32_t b = val2;
|
|
||||||
uint32_t c = 0;
|
|
||||||
|
|
||||||
bitMixerFinal(a,b,c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Hash a uLabel triplet
|
|
||||||
inline unsigned intHash
|
|
||||||
(
|
|
||||||
const uLabel& val1,
|
|
||||||
const uLabel& val2,
|
|
||||||
const uLabel& val3
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint32_t a = val1;
|
|
||||||
uint32_t b = val2;
|
|
||||||
uint32_t c = val3;
|
|
||||||
|
|
||||||
bitMixer(a,b,c);
|
|
||||||
|
|
||||||
bitMixerFinal(a,b,c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
//- Hash a uLabel
|
|
||||||
inline unsigned intHash
|
|
||||||
(
|
|
||||||
const uLabel& val1
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint32_t a = val1 >> 32;
|
|
||||||
uint32_t b = val1 & 0xFFFFFFFF;
|
|
||||||
uint32_t c = 0;
|
|
||||||
|
|
||||||
bitMixerFinal(a,b,c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Hash a uLabel pair
|
|
||||||
inline unsigned intHash
|
|
||||||
(
|
|
||||||
const uLabel& val1,
|
|
||||||
const uLabel& val2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint32_t a = val1 >> 32;
|
|
||||||
uint32_t b = val1 & 0xFFFFFFFF;
|
|
||||||
uint32_t c = val2 >> 32;
|
|
||||||
|
|
||||||
bitMixer(a,b,c);
|
|
||||||
|
|
||||||
a += val2 & 0xFFFFFFFF;
|
|
||||||
|
|
||||||
bitMixerFinal(a,b,c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Hash a uLabel triplet
|
|
||||||
inline unsigned intHash
|
|
||||||
(
|
|
||||||
const uLabel& val1,
|
|
||||||
const uLabel& val2,
|
|
||||||
const uLabel& val3
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint32_t a = val1 >> 32;
|
|
||||||
uint32_t b = val1 & 0xFFFFFFFF;
|
|
||||||
uint32_t c = val2 >> 32;
|
|
||||||
|
|
||||||
bitMixer(a,b,c);
|
|
||||||
|
|
||||||
a += val2 & 0xFFFFFFFF;
|
|
||||||
b += val3 >> 32;
|
|
||||||
c += val3 & 0xFFFFFFFF;
|
|
||||||
|
|
||||||
bitMixerFinal(a,b,c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//- Hash a label as uLabel
|
|
||||||
inline unsigned intHash(const label& val)
|
|
||||||
{
|
|
||||||
return intHash(static_cast<uLabel>(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Hash a label pair
|
|
||||||
inline unsigned intHash
|
|
||||||
(
|
|
||||||
const label& val1,
|
|
||||||
const label& val2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return intHash
|
|
||||||
(
|
|
||||||
static_cast<uLabel>(val1),
|
|
||||||
static_cast<uLabel>(val2)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Hash a label triplet
|
|
||||||
inline unsigned intHash
|
|
||||||
(
|
|
||||||
const label& val1,
|
|
||||||
const label& val2,
|
|
||||||
const label& val3
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return intHash
|
|
||||||
(
|
|
||||||
static_cast<uLabel>(val1),
|
|
||||||
static_cast<uLabel>(val2),
|
|
||||||
static_cast<uLabel>(val3)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
inline unsigned intHashCommutative(const label s1, const label s2)
|
|
||||||
{
|
|
||||||
if (s1 < s2)
|
|
||||||
{
|
|
||||||
intHash(s1, s2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
intHash(s2, s1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Hashing
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -37,8 +37,8 @@ namespace Foam
|
|||||||
const char* const pTraits<label>::typeName = "label";
|
const char* const pTraits<label>::typeName = "label";
|
||||||
const label pTraits<label>::zero = 0;
|
const label pTraits<label>::zero = 0;
|
||||||
const label pTraits<label>::one = 1;
|
const label pTraits<label>::one = 1;
|
||||||
const label pTraits<label>::max = labelMax;
|
|
||||||
const label pTraits<label>::min = labelMin;
|
const label pTraits<label>::min = labelMin;
|
||||||
|
const label pTraits<label>::max = labelMax;
|
||||||
|
|
||||||
const char* pTraits<label>::componentNames[] = { "x" };
|
const char* pTraits<label>::componentNames[] = { "x" };
|
||||||
|
|
||||||
|
|||||||
@ -43,24 +43,27 @@ Description
|
|||||||
|
|
||||||
|
|
||||||
#if FOAM_LABEL64
|
#if FOAM_LABEL64
|
||||||
# define WANTEDRANGE 9000000000000000000
|
# define FOAM_LABEL_MAX 9000000000000000000
|
||||||
#else
|
#else
|
||||||
# define WANTEDRANGE 2000000000
|
# define FOAM_LABEL_MAX 2000000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if INT_MAX > WANTEDRANGE
|
#if INT_MAX > FOAM_LABEL_MAX
|
||||||
|
|
||||||
// Define label as an int
|
// Define label as an int
|
||||||
|
|
||||||
#include "int.H"
|
# undef FOAM_LABEL_MAX
|
||||||
|
# define FOAM_LABEL_MAX INT_MAX
|
||||||
|
|
||||||
|
# include "int.H"
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
typedef int label;
|
typedef int label;
|
||||||
|
|
||||||
static const label labelMax = INT_MAX;
|
|
||||||
static const label labelMin = INT_MIN;
|
static const label labelMin = INT_MIN;
|
||||||
|
static const label labelMax = INT_MAX;
|
||||||
|
|
||||||
inline label readLabel(Istream& is)
|
inline label readLabel(Istream& is)
|
||||||
{
|
{
|
||||||
@ -70,19 +73,21 @@ namespace Foam
|
|||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
#elif LONG_MAX > WANTEDRANGE
|
#elif LONG_MAX > FOAM_LABEL_MAX
|
||||||
|
|
||||||
// Define label as a long
|
// Define label as a long
|
||||||
|
|
||||||
#include "int.H"
|
# undef FOAM_LABEL_MAX
|
||||||
#include "long.H"
|
# define FOAM_LABEL_MAX LONG_MAX
|
||||||
|
|
||||||
|
# include "int.H"
|
||||||
|
# include "long.H"
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
typedef long label;
|
typedef long label;
|
||||||
|
|
||||||
static const label labelMax = LONG_MAX;
|
|
||||||
static const label labelMin = LONG_MIN;
|
static const label labelMin = LONG_MIN;
|
||||||
|
static const label labelMax = LONG_MAX;
|
||||||
|
|
||||||
inline label readLabel(Istream& is)
|
inline label readLabel(Istream& is)
|
||||||
{
|
{
|
||||||
@ -92,20 +97,23 @@ namespace Foam
|
|||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
#elif LLONG_MAX > WANTEDRANGE
|
#elif LLONG_MAX > FOAM_LABEL_MAX
|
||||||
|
|
||||||
// Define label as a long long
|
// Define label as a long long
|
||||||
|
|
||||||
#include "int.H"
|
# undef FOAM_LABEL_MAX
|
||||||
#include "long.H"
|
# define FOAM_LABEL_MAX LLONG_MAX
|
||||||
#include "longLong.H"
|
|
||||||
|
# include "int.H"
|
||||||
|
# include "long.H"
|
||||||
|
# include "longLong.H"
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
typedef long long label;
|
typedef long long label;
|
||||||
|
|
||||||
static const label labelMax = LLONG_MAX;
|
|
||||||
static const label labelMin = LLONG_MIN;
|
static const label labelMin = LLONG_MIN;
|
||||||
|
static const label labelMax = LLONG_MAX;
|
||||||
|
|
||||||
inline label readLabel(Istream& is)
|
inline label readLabel(Istream& is)
|
||||||
{
|
{
|
||||||
@ -125,7 +133,7 @@ namespace Foam
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// template specialisation for pTraits<label>
|
//- template specialization for pTraits<label>
|
||||||
template<>
|
template<>
|
||||||
class pTraits<label>
|
class pTraits<label>
|
||||||
{
|
{
|
||||||
@ -151,8 +159,8 @@ public:
|
|||||||
static const char* componentNames[];
|
static const char* componentNames[];
|
||||||
static const label zero;
|
static const label zero;
|
||||||
static const label one;
|
static const label one;
|
||||||
static const label max;
|
|
||||||
static const label min;
|
static const label min;
|
||||||
|
static const label max;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
|
|||||||
@ -37,8 +37,8 @@ namespace Foam
|
|||||||
const char* const pTraits<uLabel>::typeName = "uLabel";
|
const char* const pTraits<uLabel>::typeName = "uLabel";
|
||||||
const uLabel pTraits<uLabel>::zero = 0;
|
const uLabel pTraits<uLabel>::zero = 0;
|
||||||
const uLabel pTraits<uLabel>::one = 1;
|
const uLabel pTraits<uLabel>::one = 1;
|
||||||
const uLabel pTraits<uLabel>::max = uLabelMax;
|
|
||||||
const uLabel pTraits<uLabel>::min = uLabelMin;
|
const uLabel pTraits<uLabel>::min = uLabelMin;
|
||||||
|
const uLabel pTraits<uLabel>::max = uLabelMax;
|
||||||
|
|
||||||
const char* pTraits<uLabel>::componentNames[] = { "x" };
|
const char* pTraits<uLabel>::componentNames[] = { "x" };
|
||||||
|
|
||||||
|
|||||||
@ -43,24 +43,27 @@ SeeAlso
|
|||||||
|
|
||||||
|
|
||||||
#if FOAM_LABEL64
|
#if FOAM_LABEL64
|
||||||
# define WANTEDURANGE 18000000000000000000
|
# define FOAM_ULABEL_MAX 18000000000000000000
|
||||||
#else
|
#else
|
||||||
# define WANTEDURANGE 4000000000
|
# define FOAM_ULABEL_MAX 4000000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if UINT_MAX > WANTEDURANGE
|
#if UINT_MAX > FOAM_ULABEL_MAX
|
||||||
|
|
||||||
// Define uLabel as an unsigned int
|
// Define uLabel as an unsigned int
|
||||||
|
|
||||||
#include "uint.H"
|
# undef FOAM_ULABEL_MAX
|
||||||
|
# define FOAM_ULABEL_MAX UINT_MAX
|
||||||
|
|
||||||
|
# include "uint.H"
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
typedef unsigned int uLabel;
|
typedef unsigned int uLabel;
|
||||||
|
|
||||||
static const uLabel uLabelMax = UINT_MAX;
|
|
||||||
static const uLabel uLabelMin = 0;
|
static const uLabel uLabelMin = 0;
|
||||||
|
static const uLabel uLabelMax = UINT_MAX;
|
||||||
|
|
||||||
inline uLabel readULabel(Istream& is)
|
inline uLabel readULabel(Istream& is)
|
||||||
{
|
{
|
||||||
@ -70,19 +73,22 @@ namespace Foam
|
|||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
#elif ULONG_MAX > WANTEDURANGE
|
#elif ULONG_MAX > FOAM_ULABEL_MAX
|
||||||
|
|
||||||
// Define uLabel as an unsigned long
|
// Define uLabel as an unsigned long
|
||||||
|
|
||||||
#include "uint.H"
|
# undef FOAM_ULABEL_MAX
|
||||||
#include "ulong.H"
|
# define FOAM_ULABEL_MAX ULONG_MAX
|
||||||
|
|
||||||
|
# include "uint.H"
|
||||||
|
# include "ulong.H"
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
typedef unsigned long uLabel;
|
typedef unsigned long uLabel;
|
||||||
|
|
||||||
static const uLabel uLabelMax = ULONG_MAX;
|
|
||||||
static const uLabel uLabelMin = 0;
|
static const uLabel uLabelMin = 0;
|
||||||
|
static const uLabel uLabelMax = ULONG_MAX;
|
||||||
|
|
||||||
inline uLabel readULabel(Istream& is)
|
inline uLabel readULabel(Istream& is)
|
||||||
{
|
{
|
||||||
@ -92,11 +98,13 @@ namespace Foam
|
|||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
#elif ULLONG_MAX > WANTEDURANGE
|
#elif ULLONG_MAX > FOAM_ULABEL_MAX
|
||||||
|
|
||||||
// Define uLabel as an unsigned long long
|
// Define uLabel as an unsigned long long
|
||||||
|
|
||||||
#error "Not implemented yet"
|
# undef FOAM_ULABEL_MAX
|
||||||
|
|
||||||
|
# error "Not implemented yet"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -109,7 +117,7 @@ namespace Foam
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// template specialisation for pTraits<label>
|
//- template specialization for pTraits<uLabel>
|
||||||
template<>
|
template<>
|
||||||
class pTraits<uLabel>
|
class pTraits<uLabel>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -48,7 +48,7 @@ class Ostream;
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
//- Return a string representation of an ulong
|
//- Return a string representation of a ulong
|
||||||
word name(const unsigned long);
|
word name(const unsigned long);
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -45,7 +45,7 @@ Foam::word Foam::name(const unsigned long val)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::Istream& Foam::operator>>(Istream& is, unsigned long& i)
|
Foam::Istream& Foam::operator>>(Istream& is, unsigned long& val)
|
||||||
{
|
{
|
||||||
token t(is);
|
token t(is);
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ Foam::Istream& Foam::operator>>(Istream& is, unsigned long& i)
|
|||||||
|
|
||||||
if (t.isLabel())
|
if (t.isLabel())
|
||||||
{
|
{
|
||||||
i = static_cast<unsigned long>(t.labelToken());
|
val = static_cast<unsigned long>(t.labelToken());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -85,9 +85,9 @@ unsigned long Foam::readUlong(Istream& is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::operator<<(Ostream& os, const unsigned long i)
|
Foam::Ostream& Foam::operator<<(Ostream& os, const unsigned long val)
|
||||||
{
|
{
|
||||||
os.write(label(i));
|
os.write(label(val));
|
||||||
os.check("Ostream& operator<<(Ostream&, const unsigned long)");
|
os.check("Ostream& operator<<(Ostream&, const unsigned long)");
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,7 @@ SourceFiles
|
|||||||
#define string_H
|
#define string_H
|
||||||
|
|
||||||
#include "char.H"
|
#include "char.H"
|
||||||
|
#include "Hasher.H"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -92,7 +93,7 @@ public:
|
|||||||
hash()
|
hash()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline unsigned operator()(const string&) const;
|
inline unsigned operator()(const string&, unsigned seed = 0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -198,19 +198,11 @@ inline Foam::string Foam::string::operator()(const size_type n) const
|
|||||||
|
|
||||||
inline unsigned Foam::string::hash::operator()
|
inline unsigned Foam::string::hash::operator()
|
||||||
(
|
(
|
||||||
const string& key
|
const string& key,
|
||||||
|
unsigned seed
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const size_type len = key.length();
|
return Hasher(key.data(), key.size(), seed);
|
||||||
const char *data = key.data();
|
|
||||||
|
|
||||||
register unsigned val = 0;
|
|
||||||
for (register size_type i=0; i < len; ++data, ++i)
|
|
||||||
{
|
|
||||||
val = (val << 1) ^ *data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -864,7 +864,7 @@ void Foam::fvMeshDistribute::findCouples
|
|||||||
{
|
{
|
||||||
// Store domain neighbour as map so we can easily look for pair
|
// Store domain neighbour as map so we can easily look for pair
|
||||||
// with same face+proc.
|
// with same face+proc.
|
||||||
HashTable<label, labelPair, labelPairHash> map(domainFace.size());
|
HashTable<label, labelPair, labelPair::Hash<> > map(domainFace.size());
|
||||||
|
|
||||||
forAll(domainFace, bFaceI)
|
forAll(domainFace, bFaceI)
|
||||||
{
|
{
|
||||||
@ -884,8 +884,8 @@ void Foam::fvMeshDistribute::findCouples
|
|||||||
{
|
{
|
||||||
labelPair myData(sourceFace[bFaceI], sourceProc[bFaceI]);
|
labelPair myData(sourceFace[bFaceI], sourceProc[bFaceI]);
|
||||||
|
|
||||||
HashTable<label, labelPair, labelPairHash>::const_iterator iter =
|
HashTable<label, labelPair, labelPair::Hash<> >::const_iterator
|
||||||
map.find(myData);
|
iter = map.find(myData);
|
||||||
|
|
||||||
if (iter != map.end())
|
if (iter != map.end())
|
||||||
{
|
{
|
||||||
|
|||||||
@ -106,23 +106,6 @@ class fvMeshDistribute
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//- Hash labelPair.
|
|
||||||
// Note non-commutative since p[0] is face, p[1] is processor.
|
|
||||||
class labelPairHash
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
labelPairHash()
|
|
||||||
{}
|
|
||||||
|
|
||||||
unsigned operator()(const labelPair& p) const
|
|
||||||
{
|
|
||||||
uLabel p0 = static_cast<uLabel>(p[0]);
|
|
||||||
uLabel p1 = static_cast<uLabel>(p[1]);
|
|
||||||
return (p0*p0 + p0+p1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
|||||||
@ -51,13 +51,13 @@ namespace Foam
|
|||||||
defineTypeNameAndDebug(hexRef8, 0);
|
defineTypeNameAndDebug(hexRef8, 0);
|
||||||
|
|
||||||
//- Reduction class. If x and y are not equal assign value.
|
//- Reduction class. If x and y are not equal assign value.
|
||||||
template< int value >
|
template<int value>
|
||||||
class ifEqEqOp
|
class ifEqEqOp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void operator()( label& x, const label& y ) const
|
void operator()(label& x, const label& y) const
|
||||||
{
|
{
|
||||||
x = (x==y) ? x:value;
|
x = (x==y) ? x : value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user