Modified hash to make it more independent of the choice of test names.

This commit is contained in:
Sergio Losilla 2020-11-17 11:16:36 +02:00 committed by Martin Hořeňovský
parent ff349a50bf
commit 3ba745552b

View File

@ -22,24 +22,27 @@ namespace Catch {
namespace { namespace {
struct TestHasher { struct TestHasher {
explicit TestHasher(Catch::SimplePcg32& rng_instance) { using hash_t = uint64_t;
basis = rng_instance();
basis <<= 32; explicit TestHasher(hash_t seed): m_seed{seed} {
basis |= rng_instance();
} }
uint64_t basis; hash_t operator()(TestCase const& t) const {
// FNV-1a hash with multiplication fold.
uint64_t operator()(TestCase const& t) const { const hash_t prime = 1099511628211u;
// Modified FNV-1a hash hash_t hash = 14695981039346656037u;
static constexpr uint64_t prime = 1099511628211;
uint64_t hash = basis;
for ( const char c : t.name ) { for ( const char c : t.name ) {
hash ^= c; hash ^= c;
hash *= prime; hash *= prime;
} }
return hash; hash ^= m_seed;
hash *= prime;
const uint32_t low{ static_cast<uint32_t>( hash ) };
const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) };
return hash_t{ low * high };
} }
private:
hash_t m_seed;
}; };
} // end unnamed namespace } // end unnamed namespace
@ -58,9 +61,9 @@ namespace Catch {
case RunTests::InRandomOrder: { case RunTests::InRandomOrder: {
seedRng( config ); seedRng( config );
TestHasher h( rng() ); TestHasher h{ config.rngSeed() };
using hashedTest = std::pair<uint64_t, TestCase const*>; using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;
std::vector<hashedTest> indexed_tests; std::vector<hashedTest> indexed_tests;
indexed_tests.reserve( unsortedTestCases.size() ); indexed_tests.reserve( unsortedTestCases.size() );