diff --git a/main.cpp b/main.cpp index 5bdaaeca..f62c4b16 100644 --- a/main.cpp +++ b/main.cpp @@ -104,7 +104,6 @@ //----------------------------------------------------------------------------- // Locally-visible configuration -static bool g_drawDiagram = false; static bool g_forceSummary = false; // Setting to test more thoroughly. @@ -272,7 +271,8 @@ static HashInfo::endianness parse_endian( const char * str ) { //----------------------------------------------------------------------------- // Self-tests - verify that hashes work correctly -static void HashSelfTestAll( bool verbose ) { +static void HashSelfTestAll( flags_t flags ) { + bool verbose = REPORT(VERBOSE, flags); bool pass = true; printf("[[[ VerifyAll Tests ]]]\n\n"); @@ -298,14 +298,14 @@ static bool HashSelfTest( const HashInfo * hinfo ) { return result; } -static void HashSanityTestAll( bool verbose ) { +static void HashSanityTestAll( flags_t flags ) { const uint64_t mask_flags = FLAG_HASH_MOCK | FLAG_HASH_CRYPTOGRAPHIC; uint64_t prev_flags = FLAG_HASH_MOCK; std::vector allHashes = findAllHashes(); printf("[[[ SanityAll Tests ]]]\n\n"); - SanityTestHeader(verbose); + SanityTestHeader(flags); for (const HashInfo * h: allHashes) { if ((h->hash_flags & mask_flags) != prev_flags) { printf("\n"); @@ -315,7 +315,7 @@ static void HashSanityTestAll( bool verbose ) { printf("%s : hash initialization failed!", h->name); continue; } - SanityTest(h, true, verbose); + SanityTest(h, flags, true); } printf("\n"); } @@ -323,14 +323,14 @@ static void HashSanityTestAll( bool verbose ) { //----------------------------------------------------------------------------- // Quickly speed test all hashes -static void HashSpeedTestAll( bool verbose ) { +static void HashSpeedTestAll( flags_t flags ) { const uint64_t mask_flags = FLAG_HASH_MOCK | FLAG_HASH_CRYPTOGRAPHIC; uint64_t prev_flags = FLAG_HASH_MOCK; std::vector allHashes = findAllHashes(); printf("[[[ Short Speed Tests ]]]\n\n"); - ShortSpeedTestHeader(verbose); + ShortSpeedTestHeader(flags); for (const HashInfo * h: allHashes) { if ((h->hash_flags & mask_flags) != prev_flags) { printf("\n"); @@ -340,7 +340,7 @@ static void HashSpeedTestAll( bool verbose ) { printf("%s : hash initialization failed!", h->name); continue; } - ShortSpeedTest(h, verbose); + ShortSpeedTest(h, flags); } printf("\n"); } @@ -371,7 +371,7 @@ static void print_pvaluecounts( void ) { //----------------------------------------------------------------------------- template -static bool test( const HashInfo * hInfo ) { +static bool test( const HashInfo * hInfo, const flags_t flags ) { bool result = true; if (g_testAll) { @@ -416,7 +416,7 @@ static bool test( const HashInfo * hInfo ) { printf("[[[ Sanity Tests ]]]\n\n"); result &= HashSelfTest(hInfo); - result &= (SanityTest(hInfo) || hInfo->isMock()); + result &= (SanityTest(hInfo, flags) || hInfo->isMock()); printf("\n"); } @@ -424,137 +424,137 @@ static bool test( const HashInfo * hInfo ) { // Speed tests if (g_testSpeed) { - SpeedTest(hInfo); + SpeedTest(hInfo, flags); } if (g_testHashmap) { - result &= HashMapTest(hInfo, g_drawDiagram, g_testExtra); + result &= HashMapTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Avalanche tests if (g_testAvalanche) { - result &= AvalancheTest(hInfo, g_drawDiagram, g_testExtra); + result &= AvalancheTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Bit Independence Criteria if (g_testBIC) { - result &= BicTest(hInfo, g_drawDiagram, g_testExtra); + result &= BicTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'Zeroes' if (g_testZeroes) { - result &= ZeroKeyTest(hInfo, g_drawDiagram); + result &= ZeroKeyTest(hInfo, flags); } //----------------------------------------------------------------------------- // Keyset 'Cyclic' - keys of the form "abcdabcdabcd..." if (g_testCyclic) { - result &= CyclicKeyTest(hInfo, g_drawDiagram); + result &= CyclicKeyTest(hInfo, flags); } //----------------------------------------------------------------------------- // Keyset 'Sparse' - keys with all bits 0 except a few if (g_testSparse) { - result &= SparseKeyTest(hInfo, g_drawDiagram, g_testExtra); + result &= SparseKeyTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'Permutation' - all possible combinations of a set of blocks if (g_testPermutation) { - result &= PermutedKeyTest(hInfo, g_drawDiagram, g_testExtra); + result &= PermutedKeyTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'Text' if (g_testText) { - result &= TextKeyTest(hInfo, g_drawDiagram); + result &= TextKeyTest(hInfo, flags); } //----------------------------------------------------------------------------- // Keyset 'TwoBytes' - all keys up to N bytes containing two non-zero bytes if (g_testTwoBytes) { - result &= TwoBytesKeyTest(hInfo, g_drawDiagram, g_testExtra); + result &= TwoBytesKeyTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'PerlinNoise' if (g_testPerlinNoise) { - result &= PerlinNoiseTest(hInfo, g_drawDiagram, g_testExtra); + result &= PerlinNoiseTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'Bitflip' if (g_testBitflip) { - result &= BitflipTest(hInfo, g_drawDiagram, g_testExtra); + result &= BitflipTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'SeedZeroes' if (g_testSeedZeroes) { - result &= SeedZeroKeyTest(hInfo, g_drawDiagram); + result &= SeedZeroKeyTest(hInfo, flags); } //----------------------------------------------------------------------------- // Keyset 'SeedSparse' if (g_testSeedSparse) { - result &= SeedSparseTest(hInfo, g_drawDiagram); + result &= SeedSparseTest(hInfo, flags); } //----------------------------------------------------------------------------- // Keyset 'SeedBlockLen' if (g_testSeedBlockLen) { - result &= SeedBlockLenTest(hInfo, g_drawDiagram, g_testExtra); + result &= SeedBlockLenTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'SeedBlockOffset' if (g_testSeedBlockOffset) { - result &= SeedBlockOffsetTest(hInfo, g_drawDiagram, g_testExtra); + result &= SeedBlockOffsetTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'Seed' if (g_testSeed) { - result &= SeedTest(hInfo, g_drawDiagram); + result &= SeedTest(hInfo, flags); } //----------------------------------------------------------------------------- // Keyset 'SeedAvalanche' if (g_testSeedAvalanche) { - result &= SeedAvalancheTest(hInfo, g_drawDiagram, g_testExtra); + result &= SeedAvalancheTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'SeedBIC' if (g_testSeedBIC) { - result &= SeedBicTest(hInfo, g_drawDiagram, g_testExtra); + result &= SeedBicTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- // Keyset 'SeedBitflip' if (g_testSeedBitflip) { - result &= SeedBitflipTest(hInfo, g_drawDiagram, g_testExtra); + result &= SeedBitflipTest(hInfo, g_testExtra, flags); } //----------------------------------------------------------------------------- @@ -597,7 +597,7 @@ static bool test( const HashInfo * hInfo ) { //----------------------------------------------------------------------------- -static bool testHash( const char * name ) { +static bool testHash( const char * name, const flags_t flags ) { const HashInfo * hInfo; if ((hInfo = findHash(name)) == NULL) { @@ -608,22 +608,22 @@ static bool testHash( const char * name ) { // If you extend these statements by adding a new bitcount/type, you // need to adjust HASHTYPELIST in util/Instantiate.h also. if (hInfo->bits == 32) { - return test>(hInfo); + return test>(hInfo, flags); } if (hInfo->bits == 64) { - return test>(hInfo); + return test>(hInfo, flags); } if (hInfo->bits == 128) { - return test>(hInfo); + return test>(hInfo, flags); } if (hInfo->bits == 160) { - return test>(hInfo); + return test>(hInfo, flags); } if (hInfo->bits == 224) { - return test>(hInfo); + return test>(hInfo, flags); } if (hInfo->bits == 256) { - return test>(hInfo); + return test>(hInfo, flags); } printf("Invalid hash bit width %d for hash '%s'", hInfo->bits, hInfo->name); @@ -673,6 +673,7 @@ int main( int argc, const char ** argv ) { usage(); } + flags_t flags = FLAG_REPORT_PROGRESS; for (int argnb = 1; argnb < argc; argnb++) { const char * const arg = argv[argnb]; if (strncmp(arg, "--", 2) == 0) { @@ -701,7 +702,8 @@ int main( int argc, const char ** argv ) { exit(0); } if (strcmp(arg, "--verbose") == 0) { - g_drawDiagram = true; + flags |= FLAG_REPORT_VERBOSE; + flags |= FLAG_REPORT_DIAGRAMS; continue; } if (strcmp(arg, "--force-summary") == 0) { @@ -797,13 +799,13 @@ int main( int argc, const char ** argv ) { size_t timeBegin = monotonic_clock(); if (g_testVerifyAll) { - HashSelfTestAll(g_drawDiagram); + HashSelfTestAll(flags); } else if (g_testSanityAll) { - HashSanityTestAll(g_drawDiagram); + HashSanityTestAll(flags); } else if (g_testSpeedAll) { - HashSpeedTestAll(g_drawDiagram); + HashSpeedTestAll(flags); } else { - testHash(hashToTest); + testHash(hashToTest, flags); } size_t timeEnd = monotonic_clock(); diff --git a/tests/AvalancheTest.cpp b/tests/AvalancheTest.cpp index f7c90af4..531154ae 100644 --- a/tests/AvalancheTest.cpp +++ b/tests/AvalancheTest.cpp @@ -75,7 +75,7 @@ typedef unsigned a_uint; template static void calcBiasRange( const HashFn hash, const seed_t seed, std::vector & bins, const unsigned keybytes, - const uint8_t * keys, a_uint & irepp, const unsigned reps, const bool verbose ) { + const uint8_t * keys, a_uint & irepp, const unsigned reps, const flags_t flags ) { const unsigned keybits = keybytes * 8; VLA_ALLOC(uint8_t, buf, keybytes); @@ -83,7 +83,7 @@ static void calcBiasRange( const HashFn hash, const seed_t seed, std::vector static bool AvalancheImpl( HashFn hash, const seed_t seed, const unsigned keybits, - const unsigned reps, bool drawDiagram, bool drawdots ) { + const unsigned reps, flags_t flags ) { assert((keybits & 7) == 0); const unsigned keybytes = keybits / 8; @@ -135,14 +135,14 @@ static bool AvalancheImpl( HashFn hash, const seed_t seed, const unsigned keybit } if (g_NCPU == 1) { - calcBiasRange(hash, seed, bins[0], keybytes, &keys[0], irep, reps, drawdots); + calcBiasRange(hash, seed, bins[0], keybytes, &keys[0], irep, reps, flags); } else { #if defined(HAVE_THREADS) std::vector t(g_NCPU); for (unsigned i = 0; i < g_NCPU; i++) { t[i] = std::thread { calcBiasRange, hash, seed, std::ref(bins[i]), - keybytes, &keys[0], std::ref(irep), reps, drawdots + keybytes, &keys[0], std::ref(irep), reps, flags }; } for (unsigned i = 0; i < g_NCPU; i++) { @@ -160,7 +160,7 @@ static bool AvalancheImpl( HashFn hash, const seed_t seed, const unsigned keybit bool result = true; - result &= ReportBias(&bins[0][0], reps, arraysize, hashbits, drawDiagram); + result &= ReportBias(&bins[0][0], reps, arraysize, hashbits, flags); recordTestResult(result, "Avalanche", keybytes); @@ -170,10 +170,9 @@ static bool AvalancheImpl( HashFn hash, const seed_t seed, const unsigned keybit //----------------------------------------------------------------------------- template -bool AvalancheTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool AvalancheTest( const HashInfo * hinfo, bool extra, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); bool result = true; - bool drawdots = true; // .......... progress dots printf("[[[ Avalanche Tests ]]]\n\n"); @@ -188,7 +187,7 @@ bool AvalancheTest( const HashInfo * hinfo, const bool verbose, const bool extra } for (unsigned testBits: testBitsvec) { - result &= AvalancheImpl(hash, seed, testBits, 300000, verbose, drawdots); + result &= AvalancheImpl(hash, seed, testBits, 300000, flags); } printf("\n%s\n", result ? "" : g_failstr); diff --git a/tests/AvalancheTest.h b/tests/AvalancheTest.h index a61f87f6..48035374 100644 --- a/tests/AvalancheTest.h +++ b/tests/AvalancheTest.h @@ -45,4 +45,4 @@ */ template -bool AvalancheTest( const HashInfo * info, const bool verbose, const bool extra ); +bool AvalancheTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/BitIndependenceTest.cpp b/tests/BitIndependenceTest.cpp index 96d70536..568c2ee2 100644 --- a/tests/BitIndependenceTest.cpp +++ b/tests/BitIndependenceTest.cpp @@ -178,7 +178,7 @@ static void BicTestBatch( HashFn hash, const seed_t seed, std::vector template static bool BicTestImpl( HashFn hash, const seed_t seed, const size_t keybytes, - const size_t reps, bool verbose = false ) { + const size_t reps, flags_t flags ) { const size_t keybits = keybytes * 8; const size_t hashbits = hashtype::bitlen; const size_t hashbitpairs = hashbits / 2 * hashbits; @@ -234,7 +234,7 @@ static bool BicTestImpl( HashFn hash, const seed_t seed, const size_t keybytes, bool result = true; - result &= ReportChiSqIndep(&popcounts[0][0], &andcounts[0][1], keybits, hashbits, reps, verbose); + result &= ReportChiSqIndep(&popcounts[0][0], &andcounts[0][1], keybits, hashbits, reps, flags); recordTestResult(result, "BIC", keybytes); @@ -244,7 +244,7 @@ static bool BicTestImpl( HashFn hash, const seed_t seed, const size_t keybytes, //----------------------------------------------------------------------------- template -bool BicTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool BicTest( const HashInfo * hinfo, bool extra, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); size_t reps = (hinfo->bits > 128 || hinfo->isVerySlow()) ? 100000 : 600000; bool result = true; @@ -261,9 +261,9 @@ bool BicTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { } for (const auto keylen: keylens) { if (keylen <= 16) { - result &= BicTestImpl(hash, seed, keylen, reps * 2, verbose); + result &= BicTestImpl(hash, seed, keylen, reps * 2, flags); } else { - result &= BicTestImpl(hash, seed, keylen, reps, verbose); + result &= BicTestImpl(hash, seed, keylen, reps, flags); } } diff --git a/tests/BitIndependenceTest.h b/tests/BitIndependenceTest.h index 4fd2ad7c..be506c01 100644 --- a/tests/BitIndependenceTest.h +++ b/tests/BitIndependenceTest.h @@ -46,4 +46,4 @@ */ template -bool BicTest( const HashInfo * info, const bool verbose, const bool extra ); +bool BicTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/BitflipTest.cpp b/tests/BitflipTest.cpp index 95180244..e4589a0c 100644 --- a/tests/BitflipTest.cpp +++ b/tests/BitflipTest.cpp @@ -61,7 +61,7 @@ // hashes and their deltas. template -static bool BitflipTestImpl( const HashInfo * hinfo, unsigned keybits, const seed_t seed, bool drawDiagram ) { +static bool BitflipTestImpl( const HashInfo * hinfo, unsigned keybits, const seed_t seed, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); const unsigned keycount = 512 * 1024 * ((hinfo->bits <= 64) ? 3 : 4); unsigned keybytes = keybits / 8; @@ -78,12 +78,12 @@ static bool BitflipTestImpl( const HashInfo * hinfo, unsigned keybits, const see bool result = true; - if (!drawDiagram) { + if (!REPORT(VERBOSE, flags)) { printf("Testing %3d-byte keys, %d reps", keybytes, keycount); } for (unsigned keybit = 0; keybit < keybits; keybit++) { - if (drawDiagram) { + if (REPORT(VERBOSE, flags)) { printf("Testing bit %d / %d - %d keys\n", keybit, keybits, keycount); } @@ -109,14 +109,17 @@ static bool BitflipTestImpl( const HashInfo * hinfo, unsigned keybits, const see k.flipbit(keybit); } - // TestHashList() modifies the list, so keep a copy in case we need - // to run it a second time for drawDiagram == false. - if (!drawDiagram) { + // If VERBOSE reporting isn't enabled, then each test isn't being + // reported on, and so there might need to be a failure summary at + // the end of testing. If that's true, then keep a copy of the + // original list of hashes, since TestHashList() will modify it. + if (!REPORT(VERBOSE, flags)) { hashes_copy = hashes; } int curlogp = 0; - bool thisresult = TestHashList(hashes).testDistribution(true).verbose(drawDiagram).drawDiagram(drawDiagram). + bool thisresult = TestHashList(hashes).testDistribution(true). + reportFlags(flags).quiet(!REPORT(VERBOSE, flags)). sumLogp(&curlogp).testDeltas(2).dumpFailKeys([&]( hidx_t i ) { ExtBlob k(&keys[(i >> 1) * keybytes], keybytes); hashtype v; if (i & 1) { k.flipbit(keybit); } @@ -125,7 +128,7 @@ static bool BitflipTestImpl( const HashInfo * hinfo, unsigned keybits, const see printf("\t"); v.printhex(NULL); if (i & 1) { k.flipbit(keybit); } }); - if (drawDiagram) { + if (REPORT(VERBOSE, flags)) { printf("\n"); } else { progressdots(keybit, 0, keybits - 1, 20); @@ -148,7 +151,7 @@ static bool BitflipTestImpl( const HashInfo * hinfo, unsigned keybits, const see result &= thisresult; } - if (!drawDiagram) { + if (!REPORT(VERBOSE, flags)) { printf("%3d failed, worst is key bit %3d%s\n", fails, worstkeybit, result ? "" : " !!!!!"); bool ignored = TestHashList(worsthashes).testDistribution(true).testDeltas(2); unused(ignored); @@ -163,19 +166,19 @@ static bool BitflipTestImpl( const HashInfo * hinfo, unsigned keybits, const see //---------------------------------------------------------------------------- template -bool BitflipTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool BitflipTest( const HashInfo * hinfo, bool extra, flags_t flags ) { bool result = true; printf("[[[ Keyset 'Bitflip' Tests ]]]\n\n"); const seed_t seed = hinfo->Seed(g_seed); - result &= BitflipTestImpl(hinfo, 24, seed, verbose); - result &= BitflipTestImpl(hinfo, 32, seed, verbose); - result &= BitflipTestImpl(hinfo, 64, seed, verbose); + result &= BitflipTestImpl(hinfo, 24, seed, flags); + result &= BitflipTestImpl(hinfo, 32, seed, flags); + result &= BitflipTestImpl(hinfo, 64, seed, flags); if (extra && !hinfo->isVerySlow()) { - result &= BitflipTestImpl(hinfo, 160, seed, verbose); - result &= BitflipTestImpl(hinfo, 256, seed, verbose); + result &= BitflipTestImpl(hinfo, 160, seed, flags); + result &= BitflipTestImpl(hinfo, 256, seed, flags); } printf("%s\n", result ? "" : g_failstr); diff --git a/tests/BitflipTest.h b/tests/BitflipTest.h index c0bd89b4..a2cc7d72 100644 --- a/tests/BitflipTest.h +++ b/tests/BitflipTest.h @@ -49,4 +49,4 @@ // hash value when we flip 1 or more bits of the key. template -bool BitflipTest( const HashInfo * info, const bool verbose, const bool extra ); +bool BitflipTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/CyclicKeysetTest.cpp b/tests/CyclicKeysetTest.cpp index 7a5eee87..db5aba52 100644 --- a/tests/CyclicKeysetTest.cpp +++ b/tests/CyclicKeysetTest.cpp @@ -65,7 +65,7 @@ template static bool CyclicKeyImpl( HashFn hash, const seed_t seed, unsigned cycleReps, - const unsigned keycount, bool drawDiagram ) { + const unsigned keycount, flags_t flags ) { printf("Keyset 'Cyclic' - %d cycles of %d bytes - %d keys\n", cycleReps, cycleLen, keycount); std::vector hashes( keycount ); @@ -92,7 +92,7 @@ static bool CyclicKeyImpl( HashFn hash, const seed_t seed, unsigned cycleReps, //---------- - bool result = TestHashList(hashes).drawDiagram(drawDiagram).testDistribution(false).dumpFailKeys([&]( hidx_t i ) { + bool result = TestHashList(hashes).reportFlags(flags).testDistribution(false).dumpFailKeys([&]( hidx_t i ) { ExtBlob xb( &cycles[i * cycleLen], cycleLen ); printf("0x%016" PRIx64 "\t%d copies of ", g_seed, cycleReps); xb.printbytes(NULL); printf("\t"); @@ -118,7 +118,7 @@ static bool CyclicKeyImpl( HashFn hash, const seed_t seed, unsigned cycleReps, //----------------------------------------------------------------------------- template -bool CyclicKeyTest( const HashInfo * hinfo, const bool verbose ) { +bool CyclicKeyTest( const HashInfo * hinfo, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); bool result = true; @@ -128,10 +128,10 @@ bool CyclicKeyTest( const HashInfo * hinfo, const bool verbose ) { const seed_t seed = hinfo->Seed(g_seed); for (unsigned count = 4; count <= 16; count += 4) { - result &= CyclicKeyImpl(hash, seed, count, reps, verbose); - result &= CyclicKeyImpl(hash, seed, count, reps, verbose); - result &= CyclicKeyImpl(hash, seed, count, reps, verbose); - result &= CyclicKeyImpl(hash, seed, count, reps, verbose); + result &= CyclicKeyImpl(hash, seed, count, reps, flags); + result &= CyclicKeyImpl(hash, seed, count, reps, flags); + result &= CyclicKeyImpl(hash, seed, count, reps, flags); + result &= CyclicKeyImpl(hash, seed, count, reps, flags); } printf("%s\n", result ? "" : g_failstr); diff --git a/tests/CyclicKeysetTest.h b/tests/CyclicKeysetTest.h index 7119f1c4..6dd94355 100644 --- a/tests/CyclicKeysetTest.h +++ b/tests/CyclicKeysetTest.h @@ -48,4 +48,4 @@ */ template -bool CyclicKeyTest( const HashInfo * info, const bool verbose ); +bool CyclicKeyTest( const HashInfo * info, flags_t flags ); diff --git a/tests/HashMapTest.cpp b/tests/HashMapTest.cpp index aace61c5..61a14169 100644 --- a/tests/HashMapTest.cpp +++ b/tests/HashMapTest.cpp @@ -73,9 +73,9 @@ typedef phmap::flat_hash_map words, - const int trials, bool verbose ) { + const int trials, const flags_t flags ) { Rand r( 358512 ); - unused(verbose); + unused(flags); const HashFn hash = hinfo->hashFn(g_hashEndian); const seed_t seed = hinfo->Seed(g_seed ^ r.rand_u64()); @@ -201,10 +201,10 @@ static double HashMapSpeedTest( const HashInfo * hinfo, std::vector //----------------------------------------------------------------------------- static bool HashMapImpl( const HashInfo * hinfo, std::vector words, - const int trials, bool verbose ) { + const int trials, const flags_t flags ) { try { - HashMapSpeedTest(hinfo, words, trials, verbose); + HashMapSpeedTest(hinfo, words, trials, flags); } catch (...) { printf(" aborted !!!!\n"); } @@ -213,7 +213,7 @@ static bool HashMapImpl( const HashInfo * hinfo, std::vector words, //----------------------------------------------------------------------------- -bool HashMapTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool HashMapTest( const HashInfo * hinfo, bool extra, flags_t flags ) { const int trials = (hinfo->isVerySlow() || !extra) ? 5 : 50; bool result = true; @@ -229,13 +229,13 @@ bool HashMapTest( const HashInfo * hinfo, const bool verbose, const bool extra ) return result; } - std::vector words = GetWordlist(CASE_ALL, verbose); + std::vector words = GetWordlist(CASE_ALL, REPORT(VERBOSE, flags)); if (!words.size()) { printf("WARNING: Hashmap initialization failed! Skipping Hashmap test.\n"); return result; } - result &= HashMapImpl(hinfo, words, trials, verbose); + result &= HashMapImpl(hinfo, words, trials, flags); printf("\n%s\n", result ? "" : g_failstr); diff --git a/tests/HashMapTest.h b/tests/HashMapTest.h index 32678c01..1925e6f0 100644 --- a/tests/HashMapTest.h +++ b/tests/HashMapTest.h @@ -47,4 +47,4 @@ std::vector HashMapInit( bool verbose ); -bool HashMapTest( const HashInfo * info, const bool verbose, const bool extra ); +bool HashMapTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/PerlinNoiseTest.cpp b/tests/PerlinNoiseTest.cpp index fd84b9c2..4d0bddb6 100644 --- a/tests/PerlinNoiseTest.cpp +++ b/tests/PerlinNoiseTest.cpp @@ -62,7 +62,7 @@ template static bool PerlinNoise( int Xbits, int Ybits, int inputLen, int step, - const HashInfo * hinfo, bool extra, bool verbose ) { + const HashInfo * hinfo, bool extra, flags_t flags ) { assert(0 < Ybits && Ybits < 31); assert(0 < Xbits && Xbits < 31); assert( Xbits + Ybits < 31); @@ -94,8 +94,8 @@ static bool PerlinNoise( int Xbits, int Ybits, int inputLen, int step, } } - bool result = TestHashList(hashes).drawDiagram(verbose).testDistribution(extra).testDeltas(xMax). - dumpFailKeys([&]( hidx_t i ) { + bool result = TestHashList(hashes).reportFlags(flags).testDistribution(extra). + testDeltas(xMax).dumpFailKeys([&]( hidx_t i ) { uint64_t x = i % xMax; uint32_t y = i / xMax; @@ -117,15 +117,15 @@ static bool PerlinNoise( int Xbits, int Ybits, int inputLen, int step, //----------------------------------------------------------------------------- template -bool PerlinNoiseTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool PerlinNoiseTest( const HashInfo * hinfo, bool extra, flags_t flags ) { bool result = true; printf("[[[ Keyset 'PerlinNoise' Tests ]]]\n\n"); - result &= PerlinNoise(12, 12, 2, 1, hinfo, extra, verbose); + result &= PerlinNoise(12, 12, 2, 1, hinfo, extra, flags); if (extra) { - result &= PerlinNoise(12, 12, 4, 1, hinfo, extra, verbose); - result &= PerlinNoise(12, 12, 8, 1, hinfo, extra, verbose); + result &= PerlinNoise(12, 12, 4, 1, hinfo, extra, flags); + result &= PerlinNoise(12, 12, 8, 1, hinfo, extra, flags); } printf("%s\n", result ? "" : g_failstr); diff --git a/tests/PerlinNoiseTest.h b/tests/PerlinNoiseTest.h index 25483937..ca343d64 100644 --- a/tests/PerlinNoiseTest.h +++ b/tests/PerlinNoiseTest.h @@ -48,4 +48,4 @@ */ template -bool PerlinNoiseTest( const HashInfo * info, const bool verbose, const bool extra ); +bool PerlinNoiseTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/PermutationKeysetTest.cpp b/tests/PermutationKeysetTest.cpp index 469824e6..d031e6df 100644 --- a/tests/PermutationKeysetTest.cpp +++ b/tests/PermutationKeysetTest.cpp @@ -77,7 +77,7 @@ static void CombinationKeygenRecurse( uint8_t * key, int len, int maxlen, const template static bool CombinationKeyTest( HashFn hash, const seed_t seed, unsigned maxlen, const uint8_t * blocks, - uint32_t blockcount, uint32_t blocksz, const char * testdesc, bool verbose ) { + uint32_t blockcount, uint32_t blocksz, const char * testdesc, flags_t flags ) { uint8_t * key = new uint8_t[maxlen * blocksz]; uint64_t * counts = new uint64_t[maxlen + 1]; @@ -129,7 +129,7 @@ static bool CombinationKeyTest( HashFn hash, const seed_t seed, unsigned maxlen, // recursing when n hits 0. When that happens, the complete list of // indices for the nth combination has been found, and the "recursion // depth" is the length of that list. - bool result = TestHashList(hashes).drawDiagram(verbose).testDeltas(1).dumpFailKeys([&]( hidx_t n ) { + bool result = TestHashList(hashes).reportFlags(flags).testDeltas(1).dumpFailKeys([&]( hidx_t n ) { VLA_ALLOC(uint32_t, blocknums, maxlen); memset(&blocknums[0], 0, sizeof(uint32_t) * maxlen); hidx_t curlen = 0; @@ -435,7 +435,7 @@ const struct { }; template -bool PermutedKeyTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool PermutedKeyTest( const HashInfo * hinfo, bool extra, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); const int default_maxlen = 23; bool result = true; @@ -452,7 +452,7 @@ bool PermutedKeyTest( const HashInfo * hinfo, const bool verbose, const bool ext assert(test.blocks.size() == test.nrBlocks * test.szBlock); curresult &= CombinationKeyTest(hash, seed, maxlen, &(test.blocks[0]), - test.nrBlocks, test.szBlock, test.desc, verbose); + test.nrBlocks, test.szBlock, test.desc, flags); recordTestResult(curresult, "Permutation", test.desc); diff --git a/tests/PermutationKeysetTest.h b/tests/PermutationKeysetTest.h index 90506ddd..4cf5f9fb 100644 --- a/tests/PermutationKeysetTest.h +++ b/tests/PermutationKeysetTest.h @@ -48,4 +48,4 @@ */ template -bool PermutedKeyTest( const HashInfo * info, const bool verbose, const bool extra ); +bool PermutedKeyTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/SanityTest.cpp b/tests/SanityTest.cpp index db8788d7..78ce8547 100644 --- a/tests/SanityTest.cpp +++ b/tests/SanityTest.cpp @@ -71,9 +71,9 @@ static_assert(sentinel1 != sentinel2, "valid sentinel bytes in SanityTest"); // // The memory alignment of the key should not affect the hash result. -#define maybeprintf(...) if (verbose) { printf(__VA_ARGS__); } +#define maybeprintf(...) if (REPORT(VERBOSE, flags)) { printf(__VA_ARGS__); } -static bool verify_sentinel( const uint8_t * buf, size_t len, const uint8_t sentinel, bool verbose ) { +static bool verify_sentinel( const uint8_t * buf, size_t len, const uint8_t sentinel, flags_t flags ) { for (size_t i = 0; i < len; i++) { if (buf[i] != sentinel) { maybeprintf(" %" PRIu64 ": 0x%02X != 0x%02X: ", i, buf[i], sentinel); @@ -84,7 +84,7 @@ static bool verify_sentinel( const uint8_t * buf, size_t len, const uint8_t sent } template -static bool verify_hashmatch( const uint8_t * buf1, const uint8_t * buf2, size_t len, bool verbose ) { +static bool verify_hashmatch( const uint8_t * buf1, const uint8_t * buf2, size_t len, flags_t flags ) { if (likely(memcmp(buf1, buf2, len) == 0)) { return true; } @@ -106,7 +106,7 @@ static bool verify_hashmatch( const uint8_t * buf1, const uint8_t * buf2, size_t // that hashing the same thing gives the same result. // // This test can halt early, so don't add input bytes to the VCode. -bool SanityTest1( const HashInfo * hinfo, bool verbose ) { +bool SanityTest1( const HashInfo * hinfo, flags_t flags ) { Rand r( 763849 ); bool result = true; bool danger = false; @@ -131,7 +131,7 @@ bool SanityTest1( const HashInfo * hinfo, bool verbose ) { memset(hash2, sentinel2, buflen); for (int irep = 0; irep < reps; irep++) { - if (verbose) { + if (REPORT(PROGRESS, flags)) { progressdots(irep, 0, reps - 1, 10); } @@ -152,7 +152,7 @@ bool SanityTest1( const HashInfo * hinfo, bool verbose ) { } // See if the hash overflowed its output buffer - if (!verify_sentinel(hash1 + hashbytes, buflen - hashbytes, sentinel1, verbose)) { + if (!verify_sentinel(hash1 + hashbytes, buflen - hashbytes, sentinel1, flags)) { maybeprintf(" hash overflowed output buffer (pass 1):"); result = false; danger = true; @@ -163,7 +163,7 @@ bool SanityTest1( const HashInfo * hinfo, bool verbose ) { hash(buffer1, len, seed, hash2); // See if the hash overflowed output buffer this time - if (!verify_sentinel(hash2 + hashbytes, buflen - hashbytes, sentinel2, verbose)) { + if (!verify_sentinel(hash2 + hashbytes, buflen - hashbytes, sentinel2, flags)) { maybeprintf(" hash overflowed output buffer (pass 2):"); result = false; danger = true; @@ -171,7 +171,7 @@ bool SanityTest1( const HashInfo * hinfo, bool verbose ) { } // See if the hashes match, and if not then characterize the failure - if (!verify_hashmatch(hash1, hash2, hashbytes, verbose)) { + if (!verify_hashmatch(hash1, hash2, hashbytes, flags)) { result = false; goto end_sanity; } @@ -180,9 +180,9 @@ bool SanityTest1( const HashInfo * hinfo, bool verbose ) { end_sanity: if (result == false) { - printf("%s", verbose ? " FAIL !!!!!\n" : " FAIL"); + printf("%s", REPORT(VERBOSE, flags) ? " FAIL !!!!!\n" : " FAIL"); } else { - printf("%s", verbose ? " PASS\n" : " pass"); + printf("%s", REPORT(VERBOSE, flags) ? " PASS\n" : " pass"); } if (danger) { @@ -213,7 +213,7 @@ bool SanityTest1( const HashInfo * hinfo, bool verbose ) { // This test is expensive, so only run 1 rep. // // This test can halt early, so don't add input bytes to the VCode. -bool SanityTest2( const HashInfo * hinfo, bool verbose ) { +bool SanityTest2( const HashInfo * hinfo, flags_t flags ) { Rand r( 104125 ); bool result = true; @@ -242,7 +242,9 @@ bool SanityTest2( const HashInfo * hinfo, bool verbose ) { // Fill the first buffer with random data r.rand_n(buffer1, buflen); - if (verbose) { progressdots(len + irep * keymax, 1, reps * keymax, 10); } + if (REPORT(PROGRESS, flags)) { + progressdots(len + irep * keymax, 1, reps * keymax, 10); + } // Record the hash of key1. hash1 becomes the correct // answer that the rest of the loop will test against. hash(key1, len, seed, hash1); @@ -265,7 +267,7 @@ bool SanityTest2( const HashInfo * hinfo, bool verbose ) { key1.flipbit(bit); hash(key1, len, seed, hash2); - if (!verify_hashmatch(hash1, hash2, hashbytes, verbose)) { + if (!verify_hashmatch(hash1, hash2, hashbytes, flags)) { result = false; goto end_sanity; } @@ -294,7 +296,7 @@ bool SanityTest2( const HashInfo * hinfo, bool verbose ) { seed = hinfo->Seed(0, HashInfo::SEED_FORCED); hash(key1, len, seed, hash2); - if (!verify_hashmatch(hash1, hash2, hashbytes, verbose)) { + if (!verify_hashmatch(hash1, hash2, hashbytes, flags)) { result = false; goto end_sanity; } @@ -355,9 +357,9 @@ bool SanityTest2( const HashInfo * hinfo, bool verbose ) { end_sanity: if (result == false) { - printf("%s", verbose ? " FAIL !!!!!\n" : " ... FAIL"); + printf("%s", REPORT(VERBOSE, flags) ? " FAIL !!!!!\n" : " ... FAIL"); } else { - printf("%s", verbose ? " PASS\n" : " ... pass"); + printf("%s", REPORT(VERBOSE, flags) ? " PASS\n" : " ... pass"); } recordTestResult(result, "Sanity", "Basic 2"); @@ -379,8 +381,9 @@ bool SanityTest2( const HashInfo * hinfo, bool verbose ) { // Seed() is first called once in the main process, and 2) when Seed() // is called per-hash inside each thread. -static void hashthings( const HashInfo * hinfo, seed_t seed, uint32_t reps, uint32_t order, bool reseed, - bool verbose, std::vector & keys, std::vector & hashes ) { +template +static void hashthings( const HashInfo * hinfo, seed_t seed, uint32_t reps, uint32_t order, + std::vector & keys, std::vector & hashes, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); const uint32_t hashbytes = hinfo->bits / 8; @@ -403,12 +406,13 @@ static void hashthings( const HashInfo * hinfo, seed_t seed, uint32_t reps, uint const uint32_t idx = (order == 0) ? i : idxs[i]; if (reseed) { seed = hinfo->Seed(idx * UINT64_C(0xa5), HashInfo::SEED_FORCED, 1); } hash(&keys[idx * reps], idx + 1, seed, &hashes[idx * hashbytes]); - if (verbose && (order < 2)) { progressdots(i, 0, reps - 1, 4); } + if (REPORT(PROGRESS, flags) && (order < 2)) { progressdots(i, 0, reps - 1, 4); } if (order == 0) { addVCodeInput(&keys[idx * reps], idx + 1); } } } -static bool ThreadingTest( const HashInfo * hinfo, bool seedthread, bool verbose ) { +template +static bool ThreadingTest( const HashInfo * hinfo, flags_t flags ) { Rand r( 955165 ); const uint32_t hashbytes = hinfo->bits / 8; @@ -430,7 +434,7 @@ static bool ThreadingTest( const HashInfo * hinfo, bool seedthread, bool verbose maybeprintf("."); // Compute all the hashes in order on the main process in order - hashthings(hinfo, seed, reps, 0, seedthread, verbose, keys, mainhashes); + hashthings(hinfo, seed, reps, 0, keys, mainhashes, flags); addVCodeOutput(&mainhashes[0], reps * hashbytes); } else { maybeprintf("....."); @@ -443,7 +447,7 @@ static bool ThreadingTest( const HashInfo * hinfo, bool seedthread, bool verbose std::vector t(g_NCPU); for (unsigned i = 0; i < g_NCPU; i++) { t[i] = std::thread { - hashthings, hinfo, seed, reps, i + 1, seedthread, verbose, std::ref(keys), std::ref(threadhashes[i]) + hashthings, hinfo, seed, reps, i + 1, std::ref(keys), std::ref(threadhashes[i]), flags }; } for (unsigned i = 0; i < g_NCPU; i++) { @@ -455,15 +459,17 @@ static bool ThreadingTest( const HashInfo * hinfo, bool seedthread, bool verbose if (!memcmp(&mainhashes[0], &threadhashes[i][0], reps * hashbytes)) { continue; } - if (!verbose) { + if (!REPORT(VERBOSE, flags)) { result = false; break; } for (uint32_t j = 0; j < reps; j++) { if (memcmp(&mainhashes[j * hashbytes], &threadhashes[i][j * hashbytes], hashbytes) != 0) { maybeprintf("\nMismatch between main process and thread #%d at index %d\n", i, j); - if (verbose) { ExtBlob(&mainhashes[j * hashbytes], hashbytes).printhex(" main :"); } - if (verbose) { ExtBlob(&threadhashes[i][j * hashbytes], hashbytes).printhex(" thread :"); } + if (REPORT(VERBOSE, flags)) { + ExtBlob(&mainhashes[j * hashbytes], hashbytes).printhex(" main :"); + ExtBlob(&threadhashes[i][j * hashbytes], hashbytes).printhex(" thread :"); + } result = false; break; // Only breaks out of j loop } @@ -471,17 +477,17 @@ static bool ThreadingTest( const HashInfo * hinfo, bool seedthread, bool verbose } if (result == false) { - printf("%s", verbose ? " FAIL !!!!!\n\n" : " ... FAIL"); + printf("%s", REPORT(VERBOSE, flags) ? " FAIL !!!!!\n\n" : " ... FAIL"); } else { - printf("%s", verbose ? " PASS\n" : " ... pass"); + printf("%s", REPORT(VERBOSE, flags) ? " PASS\n" : " ... pass"); } recordTestResult(result, "Sanity", "Thread safety"); } else { - printf("%s", verbose ? "..... SKIPPED (ncpu set to 1)\n" : " ... skip"); + printf("%s", REPORT(VERBOSE, flags) ? "..... SKIPPED (ncpu set to 1)\n" : " ... skip"); #else } else { - printf("%s", verbose ? "..... SKIPPED (compiled without threads)\n" : " ... skip"); + printf("%s", REPORT(VERBOSE, flags) ? "..... SKIPPED (compiled without threads)\n" : " ... skip"); #endif // HAVE_THREADS } @@ -494,7 +500,7 @@ static bool ThreadingTest( const HashInfo * hinfo, bool seedthread, bool verbose //---------------------------------------------------------------------------- // Appending zero bytes to a key should always cause it to produce a different // hash value -bool AppendedZeroesTest( const HashInfo * hinfo, bool verbose ) { +bool AppendedZeroesTest( const HashInfo * hinfo, flags_t flags ) { Rand r( 434201 ); const HashFn hash = hinfo->hashFn(g_hashEndian); @@ -505,7 +511,7 @@ bool AppendedZeroesTest( const HashInfo * hinfo, bool verbose ) { maybeprintf("Running append zeroes test "); for (int rep = 0; rep < 100; rep++) { - if (verbose) { + if (REPORT(PROGRESS, flags)) { progressdots(rep, 0, 99, 10); } @@ -544,9 +550,9 @@ bool AppendedZeroesTest( const HashInfo * hinfo, bool verbose ) { done: if (result == false) { - printf("%s", verbose ? " FAIL !!!!!\n" : " ... FAIL"); + printf("%s", REPORT(VERBOSE, flags) ? " FAIL !!!!!\n" : " ... FAIL"); } else { - printf("%s", verbose ? " PASS\n" : " ... pass"); + printf("%s", REPORT(VERBOSE, flags) ? " PASS\n" : " ... pass"); } recordTestResult(result, "Sanity", "Append zeroes"); @@ -559,7 +565,7 @@ bool AppendedZeroesTest( const HashInfo * hinfo, bool verbose ) { //---------------------------------------------------------------------------- // Prepending zero bytes to a key should also always cause it to // produce a different hash value -bool PrependedZeroesTest( const HashInfo * hinfo, bool verbose ) { +bool PrependedZeroesTest( const HashInfo * hinfo, flags_t flags ) { Rand r( 14465 ); const HashFn hash = hinfo->hashFn(g_hashEndian); @@ -570,7 +576,7 @@ bool PrependedZeroesTest( const HashInfo * hinfo, bool verbose ) { maybeprintf("Running prepend zeroes test "); for (int rep = 0; rep < 100; rep++) { - if (verbose) { + if (REPORT(PROGRESS, flags)) { progressdots(rep, 0, 99, 10); } @@ -609,9 +615,9 @@ bool PrependedZeroesTest( const HashInfo * hinfo, bool verbose ) { done: if (result == false) { - printf("%s", verbose ? " FAIL !!!!!\n" : " ... FAIL"); + printf("%s", REPORT(VERBOSE, flags) ? " FAIL !!!!!\n" : " ... FAIL"); } else { - printf("%s", verbose ? " PASS\n" : " ... pass"); + printf("%s", REPORT(VERBOSE, flags) ? " PASS\n" : " ... pass"); } recordTestResult(result, "Sanity", "Prepend zeroes"); @@ -621,8 +627,8 @@ bool PrependedZeroesTest( const HashInfo * hinfo, bool verbose ) { return result; } -void SanityTestHeader( bool verbose ) { - if (verbose) { +void SanityTestHeader( flags_t flags ) { + if (REPORT(VERBOSE, flags)) { printf("%-25s %-10s %13s %13s %13s\n", "Name", "Impl ", " Sanity 1+2 ", " Zeroes ", " Thread-safe "); printf("%-25s %-10s %13s %13s %13s\n", @@ -635,12 +641,12 @@ void SanityTestHeader( bool verbose ) { } } -bool SanityTest( const HashInfo * hinfo, bool oneline, bool verbose ) { +bool SanityTest( const HashInfo * hinfo, flags_t flags, bool oneline ) { bool result = true; bool threadresult = true; if (oneline) { - if (verbose) { + if (REPORT(VERBOSE, flags)) { printf("%-25s %-10s ", hinfo->name, hinfo->impl); } else { printf("%-25s ", hinfo->name); @@ -648,14 +654,19 @@ bool SanityTest( const HashInfo * hinfo, bool oneline, bool verbose ) { } // Subtests are verbose unless oneline mode is enabled - verbose = !oneline; - - result &= SanityTest1(hinfo, verbose); - result &= SanityTest2(hinfo, verbose); - result &= AppendedZeroesTest(hinfo, verbose); - result &= PrependedZeroesTest(hinfo, verbose); - threadresult &= ThreadingTest(hinfo, false, verbose); - threadresult &= ThreadingTest(hinfo, true , verbose); + if (oneline) { + flags &= ~FLAG_REPORT_VERBOSE; + flags &= ~FLAG_REPORT_PROGRESS; + } else { + flags |= FLAG_REPORT_VERBOSE; + } + + result &= SanityTest1(hinfo, flags); + result &= SanityTest2(hinfo, flags); + result &= AppendedZeroesTest(hinfo, flags); + result &= PrependedZeroesTest(hinfo, flags); + threadresult &= ThreadingTest(hinfo, flags); + threadresult &= ThreadingTest(hinfo, flags); // If threading test cannot give meaningful results, then don't // bother printing them out. :) But still run them above so the diff --git a/tests/SanityTest.h b/tests/SanityTest.h index 2ba678ab..61748476 100644 --- a/tests/SanityTest.h +++ b/tests/SanityTest.h @@ -46,5 +46,5 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -bool SanityTest( const HashInfo * hinfo, bool oneline = false, bool verbose = false ); -void SanityTestHeader( bool verbose ); +bool SanityTest( const HashInfo * hinfo, flags_t flags = 0, bool oneline = false ); +void SanityTestHeader( flags_t flags ); diff --git a/tests/SeedAvalancheTest.cpp b/tests/SeedAvalancheTest.cpp index 9d4be48c..e679ab7b 100644 --- a/tests/SeedAvalancheTest.cpp +++ b/tests/SeedAvalancheTest.cpp @@ -75,7 +75,7 @@ typedef unsigned a_uint; template static void calcBiasRange( const HashInfo * hinfo, std::vector & bins, const unsigned keybytes, - const uint8_t * keys, const uint8_t * seeds, a_uint & irepp, const unsigned reps, const bool verbose ) { + const uint8_t * keys, const uint8_t * seeds, a_uint & irepp, const unsigned reps, const flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); hashtype A, B; @@ -84,7 +84,7 @@ static void calcBiasRange( const HashInfo * hinfo, std::vector & bins, uint64_t baseseed = 0; while ((irep = irepp++) < reps) { - if (verbose) { + if (REPORT(PROGRESS, flags)) { progressdots(irep, 0, reps - 1, 18); } @@ -113,7 +113,7 @@ static void calcBiasRange( const HashInfo * hinfo, std::vector & bins, template static bool SeedAvalancheImpl( const HashInfo * hinfo, const unsigned keybytes, - const unsigned reps, bool drawDiagram, bool drawdots ) { + const unsigned reps, flags_t flags ) { const unsigned seedbytes = seedbits / 8; const unsigned hashbits = hashtype::bitlen; const unsigned arraysize = seedbits * hashbits; @@ -140,14 +140,14 @@ static bool SeedAvalancheImpl( const HashInfo * hinfo, const unsigned keybytes, } if (g_NCPU == 1) { - calcBiasRange(hinfo, bins[0], keybytes, &keys[0], &seeds[0], irep, reps, drawdots); + calcBiasRange(hinfo, bins[0], keybytes, &keys[0], &seeds[0], irep, reps, flags); } else { #if defined(HAVE_THREADS) std::vector t(g_NCPU); for (unsigned i = 0; i < g_NCPU; i++) { t[i] = std::thread { calcBiasRange, hinfo, std::ref(bins[i]), - keybytes, &keys[0], &seeds[0], std::ref(irep), reps, drawdots + keybytes, &keys[0], &seeds[0], std::ref(irep), reps, flags }; } for (unsigned i = 0; i < g_NCPU; i++) { @@ -165,7 +165,7 @@ static bool SeedAvalancheImpl( const HashInfo * hinfo, const unsigned keybytes, bool result = true; - result &= ReportBias(&bins[0][0], reps, arraysize, hashbits, drawDiagram); + result &= ReportBias(&bins[0][0], reps, arraysize, hashbits, flags); recordTestResult(result, "SeedAvalanche", keybytes); @@ -175,9 +175,8 @@ static bool SeedAvalancheImpl( const HashInfo * hinfo, const unsigned keybytes, //----------------------------------------------------------------------------- template -bool SeedAvalancheTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool SeedAvalancheTest( const HashInfo * hinfo, bool extra, flags_t flags ) { bool result = true; - bool drawdots = true; // .......... progress dots printf("[[[ Seed Avalanche Tests ]]]\n\n"); @@ -188,11 +187,11 @@ bool SeedAvalancheTest( const HashInfo * hinfo, const bool verbose, const bool e if (hinfo->is32BitSeed()) { for (unsigned keyBytes: keyBytesvec) { - result &= SeedAvalancheImpl(hinfo, keyBytes, 300000, verbose, drawdots); + result &= SeedAvalancheImpl(hinfo, keyBytes, 300000, flags); } } else { for (unsigned keyBytes: keyBytesvec) { - result &= SeedAvalancheImpl(hinfo, keyBytes, 300000, verbose, drawdots); + result &= SeedAvalancheImpl(hinfo, keyBytes, 300000, flags); } } diff --git a/tests/SeedAvalancheTest.h b/tests/SeedAvalancheTest.h index 573286ee..d18a0eda 100644 --- a/tests/SeedAvalancheTest.h +++ b/tests/SeedAvalancheTest.h @@ -45,4 +45,4 @@ */ template -bool SeedAvalancheTest( const HashInfo * info, const bool verbose, const bool extra ); +bool SeedAvalancheTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/SeedBitIndependenceTest.cpp b/tests/SeedBitIndependenceTest.cpp index 307b7b07..1f05125d 100644 --- a/tests/SeedBitIndependenceTest.cpp +++ b/tests/SeedBitIndependenceTest.cpp @@ -126,7 +126,7 @@ static void SeedBicTestBatch( const HashInfo * hinfo, std::vector & po } template -static bool SeedBicTestImpl( const HashInfo * hinfo, const size_t keybytes, const size_t reps, bool verbose = false ) { +static bool SeedBicTestImpl( const HashInfo * hinfo, const size_t keybytes, const size_t reps, const flags_t flags ) { const size_t seedbits = hinfo->is32BitSeed() ? 32 : 64; const size_t seedbytes = seedbits / 8; const size_t hashbits = hashtype::bitlen; @@ -190,7 +190,7 @@ static bool SeedBicTestImpl( const HashInfo * hinfo, const size_t keybytes, cons bool result = true; - result &= ReportChiSqIndep(&popcounts[0][0], &andcounts[0][1], seedbits, hashbits, reps, verbose); + result &= ReportChiSqIndep(&popcounts[0][0], &andcounts[0][1], seedbits, hashbits, reps, flags); recordTestResult(result, "SeedBIC", keybytes); @@ -200,7 +200,7 @@ static bool SeedBicTestImpl( const HashInfo * hinfo, const size_t keybytes, cons //----------------------------------------------------------------------------- template -bool SeedBicTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool SeedBicTest( const HashInfo * hinfo, bool extra, flags_t flags ) { size_t reps = (hinfo->bits > 128 || hinfo->isVerySlow()) ? 100000 : 600000; bool result = true; @@ -214,9 +214,9 @@ bool SeedBicTest( const HashInfo * hinfo, const bool verbose, const bool extra ) } for (const auto keylen: keylens) { if (keylen <= 16) { - result &= SeedBicTestImpl(hinfo, keylen, reps * 2, verbose); + result &= SeedBicTestImpl(hinfo, keylen, reps * 2, flags); } else { - result &= SeedBicTestImpl(hinfo, keylen, reps, verbose); + result &= SeedBicTestImpl(hinfo, keylen, reps, flags); } } diff --git a/tests/SeedBitIndependenceTest.h b/tests/SeedBitIndependenceTest.h index 536b2562..6f28fa38 100644 --- a/tests/SeedBitIndependenceTest.h +++ b/tests/SeedBitIndependenceTest.h @@ -46,4 +46,4 @@ */ template -bool SeedBicTest( const HashInfo * info, const bool verbose, const bool extra ); +bool SeedBicTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/SeedBitflipTest.cpp b/tests/SeedBitflipTest.cpp index 7d13a212..2fa7b891 100644 --- a/tests/SeedBitflipTest.cpp +++ b/tests/SeedBitflipTest.cpp @@ -61,7 +61,7 @@ // distribution/collision tests on the hashes and their deltas. template -static bool SeedBitflipTestImpl( const HashInfo * hinfo, unsigned keybits, bool drawDiagram ) { +static bool SeedBitflipTestImpl( const HashInfo * hinfo, unsigned keybits, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); unsigned seedbytes = bigseed ? 8 : 4; unsigned seedbits = seedbytes * 8; @@ -81,12 +81,12 @@ static bool SeedBitflipTestImpl( const HashInfo * hinfo, unsigned keybits, bool bool result = true; - if (!drawDiagram) { + if (!REPORT(VERBOSE, flags)) { printf("Testing %3d-byte keys, %2d-bit seeds, %d reps", keybytes, seedbits, keycount); } for (unsigned seedbit = 0; seedbit < seedbits; seedbit++) { - if (drawDiagram) { + if (REPORT(VERBOSE, flags)) { printf("Testing seed bit %d / %d - %3d-byte keys - %d keys\n", seedbit, seedbits, keybytes, keycount); } @@ -123,14 +123,17 @@ static bool SeedBitflipTestImpl( const HashInfo * hinfo, unsigned keybits, bool seedptr += seedbytes; } - // TestHashList() modifies the list, so keep a copy in case we need - // to run it a second time for drawDiagram == false. - if (!drawDiagram) { + // If VERBOSE reporting isn't enabled, then each test isn't being + // reported on, and so there might need to be a failure summary at + // the end of testing. If that's true, then keep a copy of the + // original list of hashes, since TestHashList() will modify it. + if (!REPORT(VERBOSE, flags)) { hashes_copy = hashes; } int curlogp = 0; - bool thisresult = TestHashList(hashes).testDistribution(true).verbose(drawDiagram).drawDiagram(drawDiagram). + bool thisresult = TestHashList(hashes).testDistribution(true). + reportFlags(flags).quiet(!REPORT(VERBOSE, flags)). sumLogp(&curlogp).testDeltas(2).dumpFailKeys([&]( hidx_t i ) { ExtBlob k(&keys[(i >> 1) * keybytes], keybytes); hashtype v; seed_t iseed, hseed; @@ -144,7 +147,7 @@ static bool SeedBitflipTestImpl( const HashInfo * hinfo, unsigned keybits, bool printf("0x%016" PRIx64 "\t", (uint64_t)iseed); k.printbytes(NULL); printf("\t"); v.printhex(NULL); }); - if (drawDiagram) { + if (REPORT(VERBOSE, flags)) { printf("\n"); } else { progressdots(seedbit, 0, seedbits - 1, 10); @@ -167,7 +170,7 @@ static bool SeedBitflipTestImpl( const HashInfo * hinfo, unsigned keybits, bool result &= thisresult; } - if (!drawDiagram) { + if (!REPORT(VERBOSE, flags)) { printf("%3d failed, worst is seed bit %3d%s\n", fails, worstseedbit, result ? "" : " !!!!!"); bool ignored = TestHashList(worsthashes).testDistribution(true).testDeltas(2); unused(ignored); @@ -182,26 +185,26 @@ static bool SeedBitflipTestImpl( const HashInfo * hinfo, unsigned keybits, bool //---------------------------------------------------------------------------- template -bool SeedBitflipTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool SeedBitflipTest( const HashInfo * hinfo, bool extra, flags_t flags ) { bool result = true; printf("[[[ Seed Bitflip Tests ]]]\n\n"); if (hinfo->is32BitSeed()) { - result &= SeedBitflipTestImpl(hinfo, 24, verbose); - result &= SeedBitflipTestImpl(hinfo, 32, verbose); - result &= SeedBitflipTestImpl(hinfo, 64, verbose); + result &= SeedBitflipTestImpl(hinfo, 24, flags); + result &= SeedBitflipTestImpl(hinfo, 32, flags); + result &= SeedBitflipTestImpl(hinfo, 64, flags); if (extra && !hinfo->isSlow()) { - result &= SeedBitflipTestImpl(hinfo, 160, verbose); - result &= SeedBitflipTestImpl(hinfo, 256, verbose); + result &= SeedBitflipTestImpl(hinfo, 160, flags); + result &= SeedBitflipTestImpl(hinfo, 256, flags); } } else { - result &= SeedBitflipTestImpl(hinfo, 24, verbose); - result &= SeedBitflipTestImpl(hinfo, 32, verbose); - result &= SeedBitflipTestImpl(hinfo, 64, verbose); + result &= SeedBitflipTestImpl(hinfo, 24, flags); + result &= SeedBitflipTestImpl(hinfo, 32, flags); + result &= SeedBitflipTestImpl(hinfo, 64, flags); if (extra && !hinfo->isSlow()) { - result &= SeedBitflipTestImpl(hinfo, 160, verbose); - result &= SeedBitflipTestImpl(hinfo, 256, verbose); + result &= SeedBitflipTestImpl(hinfo, 160, flags); + result &= SeedBitflipTestImpl(hinfo, 256, flags); } } printf("%s\n", result ? "" : g_failstr); diff --git a/tests/SeedBitflipTest.h b/tests/SeedBitflipTest.h index 050ea8d5..1137c077 100644 --- a/tests/SeedBitflipTest.h +++ b/tests/SeedBitflipTest.h @@ -49,4 +49,4 @@ // happens to the hash value when we flip 1 or more bits of the seed. template -bool SeedBitflipTest( const HashInfo * info, const bool verbose, const bool extra ); +bool SeedBitflipTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/SeedBlockLenTest.cpp b/tests/SeedBlockLenTest.cpp index ae05237a..a4d1ef65 100644 --- a/tests/SeedBlockLenTest.cpp +++ b/tests/SeedBlockLenTest.cpp @@ -106,7 +106,7 @@ static void SeedBlockLenTest_Impl2( const HashInfo * hinfo, std::vector static bool SeedBlockLenTest_Impl1( const HashInfo * hinfo, size_t blockoffset_min, size_t blockoffset_incr, - size_t keylen, size_t seedmaxbits, size_t blockmaxbits, bool verbose ) { + size_t keylen, size_t seedmaxbits, size_t blockmaxbits, flags_t flags ) { assert((keylen - blocklen - blockoffset_min) >= blockoffset_incr); const size_t blockoffset_max = blockoffset_min + (((keylen - blocklen - blockoffset_min) / blockoffset_incr) * blockoffset_incr); @@ -154,7 +154,7 @@ static bool SeedBlockLenTest_Impl1( const HashInfo * hinfo, size_t blockoffset_m blockoffset_incr, blockoffset_max, seedmaxbits, blockmaxbits); } - bool result = TestHashList(hashes).drawDiagram(verbose).dumpFailKeys([&]( hidx_t i ) { + bool result = TestHashList(hashes).reportFlags(flags).dumpFailKeys([&]( hidx_t i ) { size_t blockoffset = blockoffset_min + (i % testkeys) * blockoffset_incr; i /= testkeys; uint32_t blockidx = (i % testblocks); i /= testblocks; uint32_t seedidx = i; @@ -185,7 +185,7 @@ static bool SeedBlockLenTest_Impl1( const HashInfo * hinfo, size_t blockoffset_m //----------------------------------------------------------------------------- template -bool SeedBlockLenTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool SeedBlockLenTest( const HashInfo * hinfo, bool extra, flags_t flags ) { constexpr size_t seedbits = 2; constexpr size_t blockbits = 2; constexpr size_t blocklen = 4; @@ -207,7 +207,7 @@ bool SeedBlockLenTest( const HashInfo * hinfo, const bool verbose, const bool ex for (size_t kl = minkey; kl <= maxkey; kl++) { result &= SeedBlockLenTest_Impl1(hinfo, minoffset, - incroffset, kl, seedbits, blockbits, verbose); + incroffset, kl, seedbits, blockbits, flags); } printf("%s\n", result ? "" : g_failstr); diff --git a/tests/SeedBlockLenTest.h b/tests/SeedBlockLenTest.h index 46ab7ef2..03e81707 100644 --- a/tests/SeedBlockLenTest.h +++ b/tests/SeedBlockLenTest.h @@ -48,4 +48,4 @@ */ template -bool SeedBlockLenTest( const HashInfo * info, const bool verbose, const bool extra ); +bool SeedBlockLenTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/SeedBlockOffsetTest.cpp b/tests/SeedBlockOffsetTest.cpp index ebce2659..d1aba021 100644 --- a/tests/SeedBlockOffsetTest.cpp +++ b/tests/SeedBlockOffsetTest.cpp @@ -102,7 +102,7 @@ static void SeedBlockOffsetTest_Impl2( const HashInfo * hinfo, std::vector static bool SeedBlockOffsetTest_Impl1( const HashInfo * hinfo, size_t keylen_min, size_t keylen_max, - size_t blockoffset, size_t seedmaxbits, size_t blockmaxbits, bool verbose ) { + size_t blockoffset, size_t seedmaxbits, size_t blockmaxbits, flags_t flags ) { // Compute the number of hashes that will be generated size_t testseeds = 0; @@ -137,7 +137,7 @@ static bool SeedBlockOffsetTest_Impl1( const HashInfo * hinfo, size_t keylen_min keylen_max, blockoffset, seedmaxbits, blockmaxbits); } - bool result = TestHashList(hashes).drawDiagram(verbose).dumpFailKeys([&]( hidx_t i ) { + bool result = TestHashList(hashes).reportFlags(flags).dumpFailKeys([&]( hidx_t i ) { size_t keylen = keylen_min + (i % testkeys); i /= testkeys; uint32_t blockidx = (i % testblocks); i /= testblocks; uint32_t seedidx = i; @@ -167,7 +167,7 @@ static bool SeedBlockOffsetTest_Impl1( const HashInfo * hinfo, size_t keylen_min //----------------------------------------------------------------------------- template -bool SeedBlockOffsetTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool SeedBlockOffsetTest( const HashInfo * hinfo, bool extra, flags_t flags ) { constexpr size_t seedbits = 2; constexpr size_t blockbits = 2; constexpr size_t blocklen = 4; @@ -184,7 +184,7 @@ bool SeedBlockOffsetTest( const HashInfo * hinfo, const bool verbose, const bool const size_t minkeylen = blocklen + blockoffset; const size_t maxkeylen = 31; result &= SeedBlockOffsetTest_Impl1(hinfo, minkeylen, - maxkeylen, blockoffset, seedbits, blockbits, verbose); + maxkeylen, blockoffset, seedbits, blockbits, flags); } printf("%s\n", result ? "" : g_failstr); diff --git a/tests/SeedBlockOffsetTest.h b/tests/SeedBlockOffsetTest.h index 9f97065f..0a66022c 100644 --- a/tests/SeedBlockOffsetTest.h +++ b/tests/SeedBlockOffsetTest.h @@ -48,4 +48,4 @@ */ template -bool SeedBlockOffsetTest( const HashInfo * info, const bool verbose, const bool extra ); +bool SeedBlockOffsetTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/SeedSparseTest.cpp b/tests/SeedSparseTest.cpp index 202414dc..682944e6 100644 --- a/tests/SeedSparseTest.cpp +++ b/tests/SeedSparseTest.cpp @@ -63,7 +63,7 @@ // bits set template -static bool SeedSparseTestImpl( const HashInfo * hinfo, uint32_t keylen, bool drawDiagram ) { +static bool SeedSparseTestImpl( const HashInfo * hinfo, uint32_t keylen, flags_t flags ) { assert(maxbits < 16 ); assert(keylen < MAXLEN); const HashFn hash = hinfo->hashFn(g_hashEndian); @@ -102,7 +102,7 @@ static bool SeedSparseTestImpl( const HashInfo * hinfo, uint32_t keylen, bool dr } while (iseed != 0); } - bool result = TestHashList(hashes).drawDiagram(drawDiagram).testDeltas(1).dumpFailKeys([&]( hidx_t i ) { + bool result = TestHashList(hashes).reportFlags(flags).testDeltas(1).dumpFailKeys([&]( hidx_t i ) { seed_t setbits = InverseKChooseUpToK(i, 0, maxbits, bigseed ? 64 : 32); seed_t iseed = nthlex(i, setbits); seed_t hseed = hinfo->Seed(iseed, HashInfo::SEED_FORCED); @@ -122,7 +122,7 @@ static bool SeedSparseTestImpl( const HashInfo * hinfo, uint32_t keylen, bool dr //----------------------------------------------------------------------------- template -bool SeedSparseTest( const HashInfo * hinfo, const bool verbose ) { +bool SeedSparseTest( const HashInfo * hinfo, flags_t flags ) { bool result = true; printf("[[[ Keyset 'SeedSparse' Tests ]]]\n\n"); @@ -131,11 +131,11 @@ bool SeedSparseTest( const HashInfo * hinfo, const bool verbose ) { if (hinfo->is32BitSeed()) { for (const auto testkeylen: testkeylens) { - result &= SeedSparseTestImpl(hinfo, testkeylen, verbose); + result &= SeedSparseTestImpl(hinfo, testkeylen, flags); } } else { for (const auto testkeylen: testkeylens) { - result &= SeedSparseTestImpl(hinfo, testkeylen, verbose); + result &= SeedSparseTestImpl(hinfo, testkeylen, flags); } } diff --git a/tests/SeedSparseTest.h b/tests/SeedSparseTest.h index 1e8d5900..246c213d 100644 --- a/tests/SeedSparseTest.h +++ b/tests/SeedSparseTest.h @@ -48,4 +48,4 @@ */ template -bool SeedSparseTest( const HashInfo * info, const bool verbose ); +bool SeedSparseTest( const HashInfo * info, flags_t flags ); diff --git a/tests/SeedTest.cpp b/tests/SeedTest.cpp index 04b3ba1f..1841510b 100644 --- a/tests/SeedTest.cpp +++ b/tests/SeedTest.cpp @@ -61,7 +61,7 @@ // Keyset 'Seed' - hash "the quick brown fox..." using different seeds template -static bool SeedTestImpl( const HashInfo * hinfo, uint32_t keylen, bool drawDiagram ) { +static bool SeedTestImpl( const HashInfo * hinfo, uint32_t keylen, flags_t flags ) { assert(seedbits <= 31 ); assert(keylen < MAXLEN); const HashFn hash = hinfo->hashFn(g_hashEndian); @@ -97,7 +97,7 @@ static bool SeedTestImpl( const HashInfo * hinfo, uint32_t keylen, bool drawDiag } } - bool result = TestHashList(hashes).drawDiagram(drawDiagram).testDeltas(1 << lobits).dumpFailKeys([&]( hidx_t i ) { + bool result = TestHashList(hashes).reportFlags(flags).testDeltas(1 << lobits).dumpFailKeys([&]( hidx_t i ) { seed_t seedlo = 1; seedlo = i & ((seedlo << lobits) - 1); seed_t seedhi = i; seedhi >>= lobits; seedhi <<= shiftbits; seed_t iseed = seedlo | seedhi; @@ -119,7 +119,7 @@ static bool SeedTestImpl( const HashInfo * hinfo, uint32_t keylen, bool drawDiag //----------------------------------------------------------------------------- template -bool SeedTest( const HashInfo * hinfo, const bool verbose ) { +bool SeedTest( const HashInfo * hinfo, flags_t flags ) { bool result = true; printf("[[[ Keyset 'Seed' Tests ]]]\n\n"); @@ -128,11 +128,11 @@ bool SeedTest( const HashInfo * hinfo, const bool verbose ) { if (hinfo->is32BitSeed()) { for (const auto testkeylen: testkeylens) { - result &= SeedTestImpl (hinfo, testkeylen, verbose); + result &= SeedTestImpl (hinfo, testkeylen, flags); } } else { for (const auto testkeylen: testkeylens) { - result &= SeedTestImpl (hinfo, testkeylen, verbose); + result &= SeedTestImpl (hinfo, testkeylen, flags); } } diff --git a/tests/SeedTest.h b/tests/SeedTest.h index 1a0b6ec6..75f6e3bd 100644 --- a/tests/SeedTest.h +++ b/tests/SeedTest.h @@ -48,4 +48,4 @@ */ template -bool SeedTest( const HashInfo * info, const bool verbose ); +bool SeedTest( const HashInfo * info, flags_t flags ); diff --git a/tests/SeedZeroesTest.cpp b/tests/SeedZeroesTest.cpp index bf935f99..936b0042 100644 --- a/tests/SeedZeroesTest.cpp +++ b/tests/SeedZeroesTest.cpp @@ -61,7 +61,7 @@ // with seeds with up-to-N bits set or cleared. template -static bool SeedZeroKeyImpl( const HashInfo * hinfo, const size_t maxbits, const size_t keycount, bool verbose ) { +static bool SeedZeroKeyImpl( const HashInfo * hinfo, const size_t maxbits, const size_t keycount, flags_t flags ) { assert(maxbits < 16); const HashFn hash = hinfo->hashFn(g_hashEndian); uint64_t seeds = 2 * chooseUpToK(bigseed ? 64 : 32, maxbits); @@ -100,7 +100,7 @@ static bool SeedZeroKeyImpl( const HashInfo * hinfo, const size_t maxbits, const } while (seed != 0); } - bool result = TestHashList(hashes).drawDiagram(verbose).testDeltas(2 * keycount).dumpFailKeys([&]( hidx_t i ) { + bool result = TestHashList(hashes).reportFlags(flags).testDeltas(2 * keycount).dumpFailKeys([&]( hidx_t i ) { hidx_t keylen = 1 + (i % keycount); i /= keycount; bool negate = (i & 1); i /= 2; seed_t setbits = InverseKChooseUpToK(i, 1, maxbits, bigseed ? 64 : 32); @@ -124,16 +124,16 @@ static bool SeedZeroKeyImpl( const HashInfo * hinfo, const size_t maxbits, const //----------------------------------------------------------------------------- template -bool SeedZeroKeyTest( const HashInfo * hinfo, const bool verbose ) { +bool SeedZeroKeyTest( const HashInfo * hinfo, flags_t flags ) { bool result = true; printf("[[[ Seed 'Zeroes' Tests ]]]\n\n"); for (auto sz: { 1 * 1024 + 256, 8 * 1024 + 256 }) { if (hinfo->is32BitSeed()) { - result &= SeedZeroKeyImpl(hinfo, 2, sz, verbose); + result &= SeedZeroKeyImpl(hinfo, 2, sz, flags); } else { - result &= SeedZeroKeyImpl(hinfo, 2, sz, verbose); + result &= SeedZeroKeyImpl(hinfo, 2, sz, flags); } } diff --git a/tests/SeedZeroesTest.h b/tests/SeedZeroesTest.h index 7b7caa92..2a1971a0 100644 --- a/tests/SeedZeroesTest.h +++ b/tests/SeedZeroesTest.h @@ -48,4 +48,4 @@ */ template -bool SeedZeroKeyTest( const HashInfo * info, const bool verbose ); +bool SeedZeroKeyTest( const HashInfo * info, flags_t flags ); diff --git a/tests/SparseKeysetTest.cpp b/tests/SparseKeysetTest.cpp index 30197f70..4ef2e099 100644 --- a/tests/SparseKeysetTest.cpp +++ b/tests/SparseKeysetTest.cpp @@ -84,7 +84,7 @@ static void SparseKeygenRecurse( HashFn hash, const seed_t seed, unsigned start, //---------- template -static bool SparseKeyImpl( HashFn hash, const seed_t seed, const unsigned setbits, bool inclusive, bool verbose ) { +static bool SparseKeyImpl( HashFn hash, const seed_t seed, const unsigned setbits, bool inclusive, flags_t flags ) { typedef Blob keytype; keytype k(0); @@ -106,7 +106,7 @@ static bool SparseKeyImpl( HashFn hash, const seed_t seed, const unsigned setbit SparseKeygenRecurse(hash, seed, 0, setbits, inclusive, k, hashes); - bool result = TestHashList(hashes).drawDiagram(verbose).testDeltas(1). + bool result = TestHashList(hashes).reportFlags(flags).testDeltas(1). testDistribution(false).dumpFailKeys([&]( hidx_t n ) { hidx_t t, pos = 0, maxpos = keybits - 1, laterbits = setbits; k = 0; @@ -144,7 +144,7 @@ static bool SparseKeyImpl( HashFn hash, const seed_t seed, const unsigned setbit //----------------------------------------------------------------------------- template -bool SparseKeyTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool SparseKeyTest( const HashInfo * hinfo, bool extra, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); bool result = true; @@ -155,66 +155,66 @@ bool SparseKeyTest( const HashInfo * hinfo, const bool verbose, const bool extra // Some hashes fail with small numbers of sparse keys, because the rest of the // keys will "drown out" the failure modes. These set-bit threshholds were chosen // to find these failures. Empirically, this happens above ~2^13.5 (~11586) keys. - result &= SparseKeyImpl<16, hashtype>(hash, seed, 6, true, verbose); - result &= SparseKeyImpl<24, hashtype>(hash, seed, 4, true, verbose); - result &= SparseKeyImpl<32, hashtype>(hash, seed, 4, true, verbose); - result &= SparseKeyImpl<40, hashtype>(hash, seed, 4, true, verbose); - result &= SparseKeyImpl<48, hashtype>(hash, seed, 3, true, verbose); - result &= SparseKeyImpl<56, hashtype>(hash, seed, 3, true, verbose); - result &= SparseKeyImpl<64, hashtype>(hash, seed, 3, true, verbose); - result &= SparseKeyImpl<72, hashtype>(hash, seed, 3, true, verbose); - result &= SparseKeyImpl<80, hashtype>(hash, seed, 3, true, verbose); + result &= SparseKeyImpl<16, hashtype>(hash, seed, 6, true, flags); + result &= SparseKeyImpl<24, hashtype>(hash, seed, 4, true, flags); + result &= SparseKeyImpl<32, hashtype>(hash, seed, 4, true, flags); + result &= SparseKeyImpl<40, hashtype>(hash, seed, 4, true, flags); + result &= SparseKeyImpl<48, hashtype>(hash, seed, 3, true, flags); + result &= SparseKeyImpl<56, hashtype>(hash, seed, 3, true, flags); + result &= SparseKeyImpl<64, hashtype>(hash, seed, 3, true, flags); + result &= SparseKeyImpl<72, hashtype>(hash, seed, 3, true, flags); + result &= SparseKeyImpl<80, hashtype>(hash, seed, 3, true, flags); if (extra) { - result &= SparseKeyImpl<88, hashtype>(hash, seed, 3, true, verbose); + result &= SparseKeyImpl<88, hashtype>(hash, seed, 3, true, flags); } - result &= SparseKeyImpl<96, hashtype>(hash, seed, 3, true, verbose); + result &= SparseKeyImpl<96, hashtype>(hash, seed, 3, true, flags); if (extra) { - result &= SparseKeyImpl<104, hashtype>(hash, seed, 3, true, verbose); + result &= SparseKeyImpl<104, hashtype>(hash, seed, 3, true, flags); } - result &= SparseKeyImpl<112, hashtype>(hash, seed, 3, true, verbose); + result &= SparseKeyImpl<112, hashtype>(hash, seed, 3, true, flags); // Most hashes which fail this test will fail with larger numbers of sparse keys. // These set-bit threshholds were chosen to limit the number of keys to 100,000,000. // The longer-running configurations are generally pushed to --extra mode, // except 768-bit keys, which seems to be a more-common failure point. - result &= SparseKeyImpl<16, hashtype>(hash, seed, 10, true, verbose); - result &= SparseKeyImpl<24, hashtype>(hash, seed, 20, true, verbose); - result &= SparseKeyImpl<32, hashtype>(hash, seed, 9, true, verbose); + result &= SparseKeyImpl<16, hashtype>(hash, seed, 10, true, flags); + result &= SparseKeyImpl<24, hashtype>(hash, seed, 20, true, flags); + result &= SparseKeyImpl<32, hashtype>(hash, seed, 9, true, flags); if (extra) { - result &= SparseKeyImpl<40, hashtype>(hash, seed, 7, true, verbose); - result &= SparseKeyImpl<48, hashtype>(hash, seed, 7, true, verbose); - result &= SparseKeyImpl<56, hashtype>(hash, seed, 6, true, verbose); - result &= SparseKeyImpl<64, hashtype>(hash, seed, 6, true, verbose); + result &= SparseKeyImpl<40, hashtype>(hash, seed, 7, true, flags); + result &= SparseKeyImpl<48, hashtype>(hash, seed, 7, true, flags); + result &= SparseKeyImpl<56, hashtype>(hash, seed, 6, true, flags); + result &= SparseKeyImpl<64, hashtype>(hash, seed, 6, true, flags); } - result &= SparseKeyImpl<72, hashtype>(hash, seed, 5, true, verbose); + result &= SparseKeyImpl<72, hashtype>(hash, seed, 5, true, flags); if (extra) { - result &= SparseKeyImpl<96, hashtype>(hash, seed, 5, true, verbose); + result &= SparseKeyImpl<96, hashtype>(hash, seed, 5, true, flags); } - result &= SparseKeyImpl<112, hashtype>(hash, seed, 4, true, verbose); - result &= SparseKeyImpl<128, hashtype>(hash, seed, 4, true, verbose); + result &= SparseKeyImpl<112, hashtype>(hash, seed, 4, true, flags); + result &= SparseKeyImpl<128, hashtype>(hash, seed, 4, true, flags); if (extra) { - result &= SparseKeyImpl<144, hashtype>(hash, seed, 4, true, verbose); - result &= SparseKeyImpl<192, hashtype>(hash, seed, 4, true, verbose); - result &= SparseKeyImpl<208, hashtype>(hash, seed, 4, true, verbose); + result &= SparseKeyImpl<144, hashtype>(hash, seed, 4, true, flags); + result &= SparseKeyImpl<192, hashtype>(hash, seed, 4, true, flags); + result &= SparseKeyImpl<208, hashtype>(hash, seed, 4, true, flags); } - result &= SparseKeyImpl<256, hashtype>(hash, seed, 3, true, verbose); - result &= SparseKeyImpl<384, hashtype>(hash, seed, 3, true, verbose); - result &= SparseKeyImpl<512, hashtype>(hash, seed, 3, true, verbose); + result &= SparseKeyImpl<256, hashtype>(hash, seed, 3, true, flags); + result &= SparseKeyImpl<384, hashtype>(hash, seed, 3, true, flags); + result &= SparseKeyImpl<512, hashtype>(hash, seed, 3, true, flags); if (1 || extra) { - result &= SparseKeyImpl<768, hashtype>(hash, seed, 3, true, verbose); + result &= SparseKeyImpl<768, hashtype>(hash, seed, 3, true, flags); } - result &= SparseKeyImpl< 1024, hashtype>(hash, seed, 2, true, verbose); - result &= SparseKeyImpl< 2048, hashtype>(hash, seed, 2, true, verbose); - result &= SparseKeyImpl< 4096, hashtype>(hash, seed, 2, true, verbose); - result &= SparseKeyImpl< 8192, hashtype>(hash, seed, 2, true, verbose); - result &= SparseKeyImpl<10240, hashtype>(hash, seed, 2, true, verbose); + result &= SparseKeyImpl< 1024, hashtype>(hash, seed, 2, true, flags); + result &= SparseKeyImpl< 2048, hashtype>(hash, seed, 2, true, flags); + result &= SparseKeyImpl< 4096, hashtype>(hash, seed, 2, true, flags); + result &= SparseKeyImpl< 8192, hashtype>(hash, seed, 2, true, flags); + result &= SparseKeyImpl<10240, hashtype>(hash, seed, 2, true, flags); if (extra) { - result &= SparseKeyImpl<12288, hashtype>(hash, seed, 2, true, verbose); - result &= SparseKeyImpl<16384, hashtype>(hash, seed, 2, true, verbose); + result &= SparseKeyImpl<12288, hashtype>(hash, seed, 2, true, flags); + result &= SparseKeyImpl<16384, hashtype>(hash, seed, 2, true, flags); } printf("%s\n", result ? "" : g_failstr); diff --git a/tests/SparseKeysetTest.h b/tests/SparseKeysetTest.h index 676d2ca9..a2a975e1 100644 --- a/tests/SparseKeysetTest.h +++ b/tests/SparseKeysetTest.h @@ -48,4 +48,4 @@ */ template -bool SparseKeyTest( const HashInfo * info, const bool verbose, const bool extra ); +bool SparseKeyTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/SpeedTest.cpp b/tests/SpeedTest.cpp index bb32be36..a889042f 100644 --- a/tests/SpeedTest.cpp +++ b/tests/SpeedTest.cpp @@ -229,7 +229,7 @@ static double SpeedTest( HashFn hash, seed_t seed, const int trials, const int b //----------------------------------------------------------------------------- // 256k blocks seem to give the best results. -static void BulkSpeedTest( const HashInfo * hinfo, seed_t seed, bool vary_align, bool vary_size ) { +static void BulkSpeedTest( const HashInfo * hinfo, flags_t flags, seed_t seed, bool vary_align, bool vary_size ) { const int blocksize = 256 * 1024; const int maxvary = vary_size ? 127 : 0; const int runcount = hinfo->isVerySlow() ? BULK_RUNS / 16 : (hinfo->isSlow() ? BULK_RUNS / 4 : BULK_RUNS ); @@ -255,13 +255,13 @@ static void BulkSpeedTest( const HashInfo * hinfo, seed_t seed, bool vary_align, double bestbpc = ((double)blocksize - ((double)maxvary / 2)) / cycles; double bestbps = (bestbpc * 3500000000.0 / 1073741824.0); -#if SHOW_STDDEV - printf("Alignment %2d - %5.2f bytes/cycle - %5.2f GiB/sec @ 3.5 ghz (%10.6f %10.6f stdv%8.4f%%)\n", - align, bestbpc, bestbps, cycles, stddev, 100.0 * stddev / cycles); -#else - printf("Alignment %2d - %5.2f bytes/cycle - %5.2f GiB/sec @ 3.5 ghz\n", - align, bestbpc, bestbps); -#endif + if (REPORT(VERBOSE, flags)) { + printf("Alignment %2d - %5.2f bytes/cycle - %5.2f GiB/sec @ 3.5 ghz (%10.6f %10.6f stdv%8.4f%%)\n", + align, bestbpc, bestbps, cycles, stddev, 100.0 * stddev / cycles); + } else { + printf("Alignment %2d - %5.2f bytes/cycle - %5.2f GiB/sec @ 3.5 ghz\n", + align, bestbpc, bestbps); + } sumbpc += bestbpc; } @@ -278,12 +278,12 @@ static void BulkSpeedTest( const HashInfo * hinfo, seed_t seed, bool vary_align, double bestbpc = ((double)blocksize - ((double)maxvary / 2)) / cycles; double bestbps = (bestbpc * 3500000000.0 / 1073741824.0); -#if SHOW_STDDEV - printf("Alignment rnd - %5.2f bytes/cycle - %5.2f GiB/sec @ 3.5 ghz (%10.6f stdv%8.4f%%)\n", - bestbpc, bestbps, stddev, 100.0 * stddev / cycles); -#else - printf("Alignment rnd - %5.2f bytes/cycle - %5.2f GiB/sec @ 3.5 ghz\n", bestbpc, bestbps); -#endif + if (REPORT(VERBOSE, flags)) { + printf("Alignment rnd - %5.2f bytes/cycle - %5.2f GiB/sec @ 3.5 ghz (%10.6f stdv%8.4f%%)\n", + bestbpc, bestbps, stddev, 100.0 * stddev / cycles); + } else { + printf("Alignment rnd - %5.2f bytes/cycle - %5.2f GiB/sec @ 3.5 ghz\n", bestbpc, bestbps); + } } fflush(NULL); @@ -291,7 +291,8 @@ static void BulkSpeedTest( const HashInfo * hinfo, seed_t seed, bool vary_align, //----------------------------------------------------------------------------- -static double TinySpeedTest( const HashInfo * hinfo, int maxkeysize, seed_t seed, bool verbose, bool include_vary ) { +static double TinySpeedTest( const HashInfo * hinfo, flags_t flags, int maxkeysize, + seed_t seed, bool include_vary ) { const HashFn hash = hinfo->hashFn(g_hashEndian); double sum = 0.0; @@ -303,13 +304,11 @@ static double TinySpeedTest( const HashInfo * hinfo, int maxkeysize, seed_t seed for (int i = 1; i <= maxkeysize; i++) { volatile int j = i; double cycles = SpeedTest(hash, seed, TINY_TRIALS, j, 0, 0, 0); - if (verbose) { -#if SHOW_STDDEV + if (REPORT(VERBOSE, flags)) { printf(" %2d-byte keys - %8.2f cycles/hash (%8.6f stdv%8.4f%%)\n", j, cycles, stddev, 100.0 * stddev / cycles); -#else + } else { printf(" %2d-byte keys - %8.2f cycles/hash\n", j, cycles); -#endif } sum += cycles; } @@ -320,12 +319,10 @@ static double TinySpeedTest( const HashInfo * hinfo, int maxkeysize, seed_t seed // Deliberately not counted in the Average stat, so the two can be directly compared if (include_vary) { double cycles = SpeedTest(hash, seed, TINY_TRIALS, maxkeysize, 0, maxkeysize - 1, 0); - if (verbose) { -#if SHOW_STDDEV + if (REPORT(VERBOSE, flags)) { printf(" rnd-byte keys - %8.2f cycles/hash (%8.6f stdv%8.4f%%)\n", cycles, stddev, 100.0 * stddev / cycles); -#else + } else { printf(" rnd-byte keys - %8.2f cycles/hash\n", cycles); -#endif } } @@ -333,7 +330,7 @@ static double TinySpeedTest( const HashInfo * hinfo, int maxkeysize, seed_t seed } //----------------------------------------------------------------------------- -bool SpeedTest( const HashInfo * hinfo ) { +bool SpeedTest( const HashInfo * hinfo, flags_t flags ) { bool result = true; Rand r( 164200 ); @@ -341,13 +338,13 @@ bool SpeedTest( const HashInfo * hinfo ) { const seed_t seed = hinfo->Seed(g_seed ^ r.rand_u64()); - TinySpeedTest(hinfo, 31, seed, true, true); + TinySpeedTest(hinfo, flags, 31, seed, true); printf("\n"); - BulkSpeedTest(hinfo, seed, true, false); + BulkSpeedTest(hinfo, flags, seed, true, false); printf("\n"); - BulkSpeedTest(hinfo, seed, true, true); + BulkSpeedTest(hinfo, flags, seed, true, true); printf("\n"); return result; @@ -356,9 +353,9 @@ bool SpeedTest( const HashInfo * hinfo ) { //----------------------------------------------------------------------------- // Does 5 different speed tests to try to summarize hash performance -void ShortSpeedTestHeader( bool verbose ) { +void ShortSpeedTestHeader( flags_t flags ) { printf("Bulk results are in bytes/cycle, short results are in cycles/hash\n\n"); - if (verbose) { + if (REPORT(VERBOSE, flags)) { printf("%-25s %10s %9s %17s %17s %17s %17s \n", "Name", "Impl ", "Bulk ", "1-8 bytes ", "9-16 bytes ", "17-24 bytes ", "25-32 bytes "); printf("%-25s %-10s %9s %17s %17s %17s %17s \n", @@ -373,7 +370,7 @@ void ShortSpeedTestHeader( bool verbose ) { } } -void ShortSpeedTest( const HashInfo * hinfo, bool verbose ) { +void ShortSpeedTest( const HashInfo * hinfo, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); Rand r( 20265 ); @@ -381,7 +378,7 @@ void ShortSpeedTest( const HashInfo * hinfo, bool verbose ) { const int basealignoffset = 0; printf("%-25s", hinfo->name); - if (verbose) { + if (REPORT(VERBOSE, flags)) { printf(" %-10s", hinfo->impl); } @@ -417,7 +414,7 @@ void ShortSpeedTest( const HashInfo * hinfo, bool verbose ) { worstdevpct = devpct; } } - if (verbose) { + if (REPORT(VERBOSE, flags)) { if (worstdevpct < 1.0) { printf(" %7.2f [%5.3f] ", cycles / 8.0, worstdevpct); } else { diff --git a/tests/SpeedTest.h b/tests/SpeedTest.h index 7400b181..ee72a066 100644 --- a/tests/SpeedTest.h +++ b/tests/SpeedTest.h @@ -44,6 +44,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -bool SpeedTest( const HashInfo * info ); -void ShortSpeedTest( const HashInfo * hinfo, bool verbose ); -void ShortSpeedTestHeader( bool verbose ); +bool SpeedTest( const HashInfo * info, flags_t flags ); +void ShortSpeedTest( const HashInfo * hinfo, flags_t flags ); +void ShortSpeedTestHeader( flags_t flags ); diff --git a/tests/TextKeysetTest.cpp b/tests/TextKeysetTest.cpp index 0f3822e7..808743eb 100644 --- a/tests/TextKeysetTest.cpp +++ b/tests/TextKeysetTest.cpp @@ -72,7 +72,7 @@ static void PrintTextKeyHash( HashFn hash, seed_t seed, const char * key, const // either with or without commas. template -static bool TextNumImpl( HashFn hash, const seed_t seed, const uint64_t numcount, bool verbose ) { +static bool TextNumImpl( HashFn hash, const seed_t seed, const uint64_t numcount, flags_t flags ) { std::vector hashes(numcount); printf("Keyset 'TextNum' - numbers in text form %s commas - %" PRIu64 " keys\n", commas ? "with" : "without", numcount); @@ -90,7 +90,7 @@ static bool TextNumImpl( HashFn hash, const seed_t seed, const uint64_t numcount } //---------- - bool result = TestHashList(hashes).drawDiagram(verbose).dumpFailKeys([&]( hidx_t n ) { + bool result = TestHashList(hashes).reportFlags(flags).dumpFailKeys([&]( hidx_t n ) { std::string nstr = std::to_string(n); if (commas) { for (size_t i = nstr.length(); i > 3; i -= 3) { nstr.insert(i - 3, ","); } @@ -113,7 +113,7 @@ static bool TextNumImpl( HashFn hash, const seed_t seed, const uint64_t numcount template static bool TextKeyImpl( HashFn hash, const seed_t seed, const char * prefix, const char * coreset, - const unsigned corelen, const char * suffix, bool verbose ) { + const unsigned corelen, const char * suffix, flags_t flags ) { const unsigned prefixlen = (unsigned)strlen(prefix); const unsigned suffixlen = (unsigned)strlen(suffix); const unsigned corecount = (unsigned)strlen(coreset); @@ -144,7 +144,7 @@ static bool TextKeyImpl( HashFn hash, const seed_t seed, const char * prefix, co } //---------- - bool result = TestHashList(hashes).drawDiagram(verbose).dumpFailKeys([&]( hidx_t i ) { + bool result = TestHashList(hashes).reportFlags(flags).dumpFailKeys([&]( hidx_t i ) { for (unsigned j = 0; j < corelen; j++) { key[prefixlen + j] = coreset[i % corecount]; i /= corecount; } @@ -167,7 +167,7 @@ static bool TextKeyImpl( HashFn hash, const seed_t seed, const char * prefix, co template static bool WordsKeyImpl( HashFn hash, const seed_t seed, const uint32_t keycount, const uint32_t minlen, - const uint32_t maxlen, const char * coreset, const char * name, bool verbose ) { + const uint32_t maxlen, const char * coreset, const char * name, flags_t flags ) { const uint32_t corecount = strlen(coreset); assert(maxlen >= minlen); assert(corecount <= 256); @@ -233,7 +233,7 @@ static bool WordsKeyImpl( HashFn hash, const seed_t seed, const uint32_t keycoun } //---------- - bool result = TestHashList(hashes).drawDiagram(verbose).dumpFailKeys([&]( hidx_t n ) { + bool result = TestHashList(hashes).reportFlags(flags).dumpFailKeys([&]( hidx_t n ) { uint32_t len, prefixlen = std::min(minlen, maxprefix), rngpos = 0; for (len = minlen; len <= maxlen; len++) { prefixlen = std::min(len, maxprefix); @@ -273,7 +273,7 @@ static bool WordsKeyImpl( HashFn hash, const seed_t seed, const uint32_t keycoun template static bool WordsLongImpl( HashFn hash, const seed_t seed, const long keycount, const unsigned varylen, const unsigned minlen, const unsigned maxlen, - const char * coreset, const char * name, bool verbose ) { + const char * coreset, const char * name, flags_t flags ) { const unsigned corecount = (unsigned)strlen(coreset); const size_t totalkeys = keycount * (corecount - 1) * varylen; char * key = new char[maxlen]; @@ -313,7 +313,7 @@ static bool WordsLongImpl( HashFn hash, const seed_t seed, const long keycount, } //---------- - bool result = TestHashList(hashes).drawDiagram(verbose).testDistribution(true). + bool result = TestHashList(hashes).reportFlags(flags).testDistribution(true). testDeltas(1).dumpFailKeys([&]( hidx_t n ) { unsigned l3 = n % (corecount - 1); n /= (corecount - 1); unsigned l2 = n % varylen; n /= varylen; @@ -347,8 +347,8 @@ static bool WordsLongImpl( HashFn hash, const seed_t seed, const long keycount, // Keyset 'Dict' - hash a list of dictionary words, all-lowercase or all-uppercase template -static bool WordsDictImpl( HashFn hash, const seed_t seed, bool verbose ) { - std::vector words = GetWordlist(CASE_LOWER_UPPER, verbose); +static bool WordsDictImpl( HashFn hash, const seed_t seed, flags_t flags ) { + std::vector words = GetWordlist(CASE_LOWER_UPPER, REPORT(VERBOSE, flags)); const size_t wordscount = words.size(); printf("Keyset 'Dict' - dictionary words - %zd keys\n", wordscount); @@ -364,7 +364,7 @@ static bool WordsDictImpl( HashFn hash, const seed_t seed, bool verbose ) { } //---------- - bool result = TestHashList(hashes).drawDiagram(verbose).dumpFailKeys([&](hidx_t i) { + bool result = TestHashList(hashes).reportFlags(flags).dumpFailKeys([&](hidx_t i) { PrintTextKeyHash(hash, seed, words[i].c_str(), words[i].length()); }); printf("\n"); @@ -379,7 +379,7 @@ static bool WordsDictImpl( HashFn hash, const seed_t seed, bool verbose ) { //----------------------------------------------------------------------------- template -bool TextKeyTest( const HashInfo * hinfo, const bool verbose ) { +bool TextKeyTest( const HashInfo * hinfo, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); const seed_t seed = hinfo->Seed(g_seed); const char * alnum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "; @@ -389,58 +389,58 @@ bool TextKeyTest( const HashInfo * hinfo, const bool verbose ) { bool result = true; // Dictionary words - result &= WordsDictImpl(hash, seed, verbose); + result &= WordsDictImpl(hash, seed, flags); // Numbers in text form, without and with commas - result &= TextNumImpl(hash, seed, 10000000, verbose); - result &= TextNumImpl(hash, seed, 10000000, verbose); + result &= TextNumImpl(hash, seed, 10000000, flags); + result &= TextNumImpl(hash, seed, 10000000, flags); // 6-byte keys, varying only in middle 4 bytes - result &= TextKeyImpl(hash, seed, "F" , alnum, 4, "B" , verbose); - result &= TextKeyImpl(hash, seed, "FB", alnum, 4, "" , verbose); - result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FB", verbose); + result &= TextKeyImpl(hash, seed, "F" , alnum, 4, "B" , flags); + result &= TextKeyImpl(hash, seed, "FB", alnum, 4, "" , flags); + result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FB", flags); // 10-byte keys, varying only in middle 4 bytes - result &= TextKeyImpl(hash, seed, "Foo" , alnum, 4, "Bar" , verbose); - result &= TextKeyImpl(hash, seed, "FooBar", alnum, 4, "" , verbose); - result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooBar", verbose); + result &= TextKeyImpl(hash, seed, "Foo" , alnum, 4, "Bar" , flags); + result &= TextKeyImpl(hash, seed, "FooBar", alnum, 4, "" , flags); + result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooBar", flags); // 14-byte keys, varying only in middle 4 bytes - result &= TextKeyImpl(hash, seed, "Foooo" , alnum, 4, "Baaar" , verbose); - result &= TextKeyImpl(hash, seed, "FooooBaaar", alnum, 4, "" , verbose); - result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooooBaaar", verbose); + result &= TextKeyImpl(hash, seed, "Foooo" , alnum, 4, "Baaar" , flags); + result &= TextKeyImpl(hash, seed, "FooooBaaar", alnum, 4, "" , flags); + result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooooBaaar", flags); // 18-byte keys, varying only in middle 4 bytes - result &= TextKeyImpl(hash, seed, "Foooooo" , alnum, 4, "Baaaaar" , verbose); - result &= TextKeyImpl(hash, seed, "FooooooBaaaaar", alnum, 4, "" , verbose); - result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooooooBaaaaar", verbose); + result &= TextKeyImpl(hash, seed, "Foooooo" , alnum, 4, "Baaaaar" , flags); + result &= TextKeyImpl(hash, seed, "FooooooBaaaaar", alnum, 4, "" , flags); + result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooooooBaaaaar", flags); // 22-byte keys, varying only in middle 4 bytes - result &= TextKeyImpl(hash, seed, "Foooooooo" , alnum, 4, "Baaaaaaar" , verbose); - result &= TextKeyImpl(hash, seed, "FooooooooBaaaaaaar", alnum, 4, "" , verbose); - result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooooooooBaaaaaaar", verbose); + result &= TextKeyImpl(hash, seed, "Foooooooo" , alnum, 4, "Baaaaaaar" , flags); + result &= TextKeyImpl(hash, seed, "FooooooooBaaaaaaar", alnum, 4, "" , flags); + result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooooooooBaaaaaaar", flags); // 26-byte keys, varying only in middle 4 bytes - result &= TextKeyImpl(hash, seed, "Foooooooooo" , alnum, 4, "Baaaaaaaaar" , verbose); - result &= TextKeyImpl(hash, seed, "FooooooooooBaaaaaaaaar", alnum, 4, "" , verbose); - result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooooooooooBaaaaaaaaar", verbose); + result &= TextKeyImpl(hash, seed, "Foooooooooo" , alnum, 4, "Baaaaaaaaar" , flags); + result &= TextKeyImpl(hash, seed, "FooooooooooBaaaaaaaaar", alnum, 4, "" , flags); + result &= TextKeyImpl(hash, seed, "" , alnum, 4, "FooooooooooBaaaaaaaaar", flags); // Random sets of 1..4 word-like characters - result &= WordsKeyImpl(hash, seed, 1000000, 1, 4, alnum, "alnum", verbose); + result &= WordsKeyImpl(hash, seed, 1000000, 1, 4, alnum, "alnum", flags); // Random sets of 5..8 word-like characters - result &= WordsKeyImpl(hash, seed, 1000000, 5, 8, alnum, "alnum", verbose); + result &= WordsKeyImpl(hash, seed, 1000000, 5, 8, alnum, "alnum", flags); // Random sets of 1..16 word-like characters - result &= WordsKeyImpl(hash, seed, 1000000, 1, 16, alnum, "alnum", verbose); + result &= WordsKeyImpl(hash, seed, 1000000, 1, 16, alnum, "alnum", flags); // Random sets of 1..32 word-like characters - result &= WordsKeyImpl(hash, seed, 1000000, 1, 32, alnum, "alnum", verbose); + result &= WordsKeyImpl(hash, seed, 1000000, 1, 32, alnum, "alnum", flags); // Random sets of many word-like characters, with small changes for (auto blksz: { 2048, 4096, 8192 }) { - result &= WordsLongImpl(hash, seed, 1000, 80, blksz - 80, blksz + 80, alnum, "alnum", verbose); - result &= WordsLongImpl(hash, seed, 1000, 80, blksz - 80, blksz + 80, alnum, "alnum", verbose); + result &= WordsLongImpl(hash, seed, 1000, 80, blksz - 80, blksz + 80, alnum, "alnum", flags); + result &= WordsLongImpl(hash, seed, 1000, 80, blksz - 80, blksz + 80, alnum, "alnum", flags); } printf("%s\n", result ? "" : g_failstr); diff --git a/tests/TextKeysetTest.h b/tests/TextKeysetTest.h index 870261dc..3ebee38a 100644 --- a/tests/TextKeysetTest.h +++ b/tests/TextKeysetTest.h @@ -48,4 +48,4 @@ */ template -bool TextKeyTest( const HashInfo * info, const bool verbose ); +bool TextKeyTest( const HashInfo * info, flags_t flags ); diff --git a/tests/TwoBytesKeysetTest.cpp b/tests/TwoBytesKeysetTest.cpp index 80d1c456..ef2a3d4f 100644 --- a/tests/TwoBytesKeysetTest.cpp +++ b/tests/TwoBytesKeysetTest.cpp @@ -121,12 +121,12 @@ static void TwoBytesLenKeygen( HashFn hash, const seed_t seed, size_t keylen, st } template -static bool TwoBytesTestLen( HashFn hash, const seed_t seed, size_t keylen, bool verbose, const bool extra ) { +static bool TwoBytesTestLen( HashFn hash, const seed_t seed, size_t keylen, flags_t flags, const bool extra ) { std::vector hashes; TwoBytesLenKeygen(hash, seed, keylen, hashes); - bool result = TestHashList(hashes).drawDiagram(verbose).testDeltas(1). + bool result = TestHashList(hashes).reportFlags(flags).testDeltas(1). testDistribution(extra).dumpFailKeys([&]( hidx_t i ) { VLA_ALLOC(uint8_t, key, keylen); memset(&key[0], 0, keylen); if (i < (keylen * 255)) { @@ -216,12 +216,12 @@ static void TwoBytesUpToLenKeygen( HashFn hash, const seed_t seed, size_t maxlen } template -static bool TwoBytesTestUpToLen( HashFn hash, const seed_t seed, size_t maxlen, bool verbose, const bool extra ) { +static bool TwoBytesTestUpToLen( HashFn hash, const seed_t seed, size_t maxlen, flags_t flags, const bool extra ) { std::vector hashes; TwoBytesUpToLenKeygen(hash, seed, maxlen, hashes); - bool result = TestHashList(hashes).drawDiagram(verbose).testDeltas(1). + bool result = TestHashList(hashes).reportFlags(flags).testDeltas(1). testDistribution(extra).dumpFailKeys([&]( hidx_t i ) { uint32_t keylen; VLA_ALLOC(uint8_t, key, maxlen); memset(&key[0], 0, maxlen); const uint32_t keylencnt = Sum1toN(maxlen) - 1; @@ -259,7 +259,7 @@ static bool TwoBytesTestUpToLen( HashFn hash, const seed_t seed, size_t maxlen, //----------------------------------------------------------------------------- template -bool TwoBytesKeyTest( const HashInfo * hinfo, const bool verbose, const bool extra ) { +bool TwoBytesKeyTest( const HashInfo * hinfo, bool extra, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); bool result = true; @@ -268,17 +268,17 @@ bool TwoBytesKeyTest( const HashInfo * hinfo, const bool verbose, const bool ext const seed_t seed = hinfo->Seed(g_seed); if (hinfo->isVerySlow()) { - result &= TwoBytesTestUpToLen(hash, seed, 8, verbose, true); + result &= TwoBytesTestUpToLen(hash, seed, 8, flags, true); } else { - result &= TwoBytesTestUpToLen(hash, seed, 20, verbose, extra); - result &= TwoBytesTestLen (hash, seed, 32, verbose, extra); + result &= TwoBytesTestUpToLen(hash, seed, 20, flags, extra); + result &= TwoBytesTestLen (hash, seed, 32, flags, extra); if (!hinfo->isSlow()) { - result &= TwoBytesTestLen(hash, seed, 48, verbose, extra); + result &= TwoBytesTestLen(hash, seed, 48, flags, extra); } } - result &= TwoBytesTestLen(hash, seed, 1024, verbose, true); - result &= TwoBytesTestLen(hash, seed, 2048, verbose, true); - result &= TwoBytesTestLen(hash, seed, 4096, verbose, true); + result &= TwoBytesTestLen(hash, seed, 1024, flags, true); + result &= TwoBytesTestLen(hash, seed, 2048, flags, true); + result &= TwoBytesTestLen(hash, seed, 4096, flags, true); printf("%s\n", result ? "" : g_failstr); diff --git a/tests/TwoBytesKeysetTest.h b/tests/TwoBytesKeysetTest.h index c5789be2..66a40adc 100644 --- a/tests/TwoBytesKeysetTest.h +++ b/tests/TwoBytesKeysetTest.h @@ -48,4 +48,4 @@ */ template -bool TwoBytesKeyTest( const HashInfo * info, const bool verbose, const bool extra ); +bool TwoBytesKeyTest( const HashInfo * info, bool extra, flags_t flags ); diff --git a/tests/ZeroesKeysetTest.cpp b/tests/ZeroesKeysetTest.cpp index a920a3da..90da1e77 100644 --- a/tests/ZeroesKeysetTest.cpp +++ b/tests/ZeroesKeysetTest.cpp @@ -60,7 +60,7 @@ // We reuse one block of empty bytes, otherwise the RAM cost is enormous. template -static bool ZeroKeyImpl( HashFn hash, const seed_t seed, bool verbose ) { +static bool ZeroKeyImpl( HashFn hash, const seed_t seed, flags_t flags ) { int keycount = 200 * 1024; printf("Keyset 'Zeroes' - %d keys\n", keycount); @@ -79,7 +79,7 @@ static bool ZeroKeyImpl( HashFn hash, const seed_t seed, bool verbose ) { hash(nullblock, i, seed, &hashes[i]); } - bool result = TestHashList(hashes).drawDiagram(verbose).testDeltas(1).dumpFailKeys([&]( hidx_t i ) { + bool result = TestHashList(hashes).testDeltas(1).reportFlags(flags).dumpFailKeys([&]( hidx_t i ) { printf("0x%016" PRIx64 "\t%d copies of 0x00\t", g_seed, i); hashtype v; hash(nullblock, i, seed, &v); v.printhex(NULL); }); @@ -97,7 +97,7 @@ static bool ZeroKeyImpl( HashFn hash, const seed_t seed, bool verbose ) { //----------------------------------------------------------------------------- template -bool ZeroKeyTest( const HashInfo * hinfo, const bool verbose ) { +bool ZeroKeyTest( const HashInfo * hinfo, flags_t flags ) { const HashFn hash = hinfo->hashFn(g_hashEndian); bool result = true; @@ -105,7 +105,7 @@ bool ZeroKeyTest( const HashInfo * hinfo, const bool verbose ) { const seed_t seed = hinfo->Seed(g_seed); - result &= ZeroKeyImpl(hash, seed, verbose); + result &= ZeroKeyImpl(hash, seed, flags); printf("%s\n", result ? "" : g_failstr); diff --git a/tests/ZeroesKeysetTest.h b/tests/ZeroesKeysetTest.h index 8ff346d8..5764ecf2 100644 --- a/tests/ZeroesKeysetTest.h +++ b/tests/ZeroesKeysetTest.h @@ -48,4 +48,4 @@ */ template -bool ZeroKeyTest( const HashInfo * info, const bool verbose ); +bool ZeroKeyTest( const HashInfo * info, flags_t flags ); diff --git a/util/Analyze.cpp b/util/Analyze.cpp index b4a1eb23..0c2adae8 100644 --- a/util/Analyze.cpp +++ b/util/Analyze.cpp @@ -385,13 +385,16 @@ static void CountRangedNbCollisions( std::vector & hashes, int minHBit template static bool TestCollisions( std::vector & hashes, std::vector & hashidxs, int * logpSumPtr, - KeyFn keyprint, int testDeltaNum, bool testDeltaXaxis, bool testMaxColl, bool willTestDist, - bool testHighBits, bool testLowBits, bool verbose, bool drawDiagram ) { + KeyFn keyprint, int testDeltaNum, flags_t testFlags, flags_t reportFlags ) { const unsigned hashbits = hashtype::bitlen; const hidx_t nbH = hashes.size(); - hidx_t collcount; + const bool testDeltaXaxis = TEST(DELTAXAXIS, testFlags); + const bool testMaxColl = TEST(MAXCOLLISIONS, testFlags); + const bool willTestDist = TEST(DISTRIBUTION, testFlags); + const bool testHighBits = TEST(HIGHBITS, testFlags); + const bool testLowBits = TEST(LOWBITS, testFlags); - if (verbose) { + if (!REPORT(QUIET, reportFlags)) { printf("Testing all collisions ( %3i-bit)", hashbits); } @@ -403,7 +406,8 @@ static bool TestCollisions( std::vector & hashes, std::vector // Note that FindCollisions sorts the list of hashes! std::map collisions; std::vector collisionidxs; - if (drawDiagram) { + hidx_t collcount; + if (REPORT(DIAGRAMS, reportFlags)) { collcount = FindCollisionsIndices(hashes, collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, hashidxs); } else { collcount = FindCollisions(hashes, collisions, 0); @@ -502,7 +506,7 @@ static bool TestCollisions( std::vector & hashes, std::vector if (testLowBits && (maxBits > 0)) { collcounts_rev.resize(maxBits - minBits + 1); - if (drawDiagram) { + if (REPORT(DIAGRAMS, reportFlags)) { hashes_rev.resize(nbH); for (size_t hnb = 0; hnb < nbH; hnb++) { hashes_rev[hnb] = hashes[hnb]; @@ -533,7 +537,7 @@ static bool TestCollisions( std::vector & hashes, std::vector // The data is restored to original bit ordering for other // reporting beyond TestCollisions(). There is no need to // re-sort it, though, since TestDistribution doesn't care. - if (!drawDiagram) { + if (!REPORT(DIAGRAMS, reportFlags)) { for (size_t hnb = 0; hnb < nbH; hnb++) { hashes_rev[hnb].reversebits(); } @@ -548,11 +552,11 @@ static bool TestCollisions( std::vector & hashes, std::vector // Report on complete collisions, now that the heavy lifting is complete bool result = true; int curlogp; - result &= ReportCollisions(nbH, collcount, hashbits, &curlogp, false, false, false, verbose, drawDiagram); + result &= ReportCollisions(nbH, collcount, hashbits, &curlogp, false, false, false, reportFlags); if (logpSumPtr != NULL) { *logpSumPtr += curlogp; } - if (!result && drawDiagram) { + if (!result && REPORT(DIAGRAMS, reportFlags)) { PrintCollisions(collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, keyprint, testDeltaNum, testDeltaXaxis, nbH); } @@ -569,11 +573,11 @@ static bool TestCollisions( std::vector & hashes, std::vector bool reportMaxcoll = (testMaxColl && (nbBits <= threshBits)) ? true : false; if (testHighBits) { bool thisresult = ReportCollisions(nbH, collcounts_fwd[nbBits - minBits], nbBits, - &curlogp, reportMaxcoll, true, true, verbose, drawDiagram); + &curlogp, reportMaxcoll, true, true, reportFlags); if (logpSumPtr != NULL) { *logpSumPtr += curlogp; } - if (!thisresult && drawDiagram) { + if (!thisresult && REPORT(DIAGRAMS, reportFlags)) { FindCollisionsPrefixesIndices(hashes, collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, hashidxs, nbBits, prevBitsH); PrintCollisions(collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, keyprint, @@ -584,11 +588,11 @@ static bool TestCollisions( std::vector & hashes, std::vector } if (testLowBits) { bool thisresult = ReportCollisions(nbH, collcounts_rev[nbBits - minBits], nbBits, - &curlogp, reportMaxcoll, false, true, verbose, drawDiagram); + &curlogp, reportMaxcoll, false, true, reportFlags); if (logpSumPtr != NULL) { *logpSumPtr += curlogp; } - if (!thisresult && drawDiagram) { + if (!thisresult && REPORT(DIAGRAMS, reportFlags)) { FindCollisionsPrefixesIndices(hashes_rev, collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, hashidxs_rev, nbBits, prevBitsL); PrintCollisions(collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, keyprint, @@ -603,11 +607,11 @@ static bool TestCollisions( std::vector & hashes, std::vector if (testHighBits) { int maxBits; bool thisresult = ReportBitsCollisions(nbH, &collcounts_fwd[minTBits - minBits], - minTBits, maxTBits, &curlogp, &maxBits, true, verbose, drawDiagram); + minTBits, maxTBits, &curlogp, &maxBits, true, reportFlags); if (logpSumPtr != NULL) { *logpSumPtr += curlogp; } - if (!thisresult && drawDiagram) { + if (!thisresult && REPORT(DIAGRAMS, reportFlags)) { FindCollisionsPrefixesIndices(hashes, collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, hashidxs, maxBits, hashbits + 1); PrintCollisions(collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, keyprint, @@ -618,11 +622,11 @@ static bool TestCollisions( std::vector & hashes, std::vector if (testLowBits) { int maxBits; bool thisresult = ReportBitsCollisions(nbH, &collcounts_rev[minTBits - minBits], - minTBits, maxTBits, &curlogp, &maxBits, false, verbose, drawDiagram); + minTBits, maxTBits, &curlogp, &maxBits, false, reportFlags); if (logpSumPtr != NULL) { *logpSumPtr += curlogp; } - if (!thisresult && drawDiagram) { + if (!thisresult && REPORT(DIAGRAMS, reportFlags)) { FindCollisionsPrefixesIndices(hashes_rev, collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, hashidxs_rev, maxBits, hashbits + 1); PrintCollisions(collisions, MAX_ENTRIES, MAX_PER_ENTRY, collisionidxs, keyprint, @@ -752,7 +756,7 @@ static void TestDistributionBatch( const std::vector & hashes, a_int & template static bool TestDistribution( std::vector & hashes, std::vector & hashidxs, int * logpSumPtr, - KeyFn keyprint, unsigned testDeltaNum, bool testDeltaXaxis, bool verbose, bool drawDiagram ) { + KeyFn keyprint, unsigned testDeltaNum, flags_t testFlags, flags_t reportFlags ) { const int hashbits = hashtype::bitlen; const size_t nbH = hashes.size(); int maxwidth = MaxDistBits(nbH); @@ -762,8 +766,9 @@ static bool TestDistribution( std::vector & hashes, std::vector scores(hashbits * (maxwidth - minwidth + 1)); @@ -793,13 +798,13 @@ static bool TestDistribution( std::vector & hashes, std::vector & hashes, std::vector static bool TestHashListSingle( std::vector & hashes, int * logpSumPtr, KeyFn keyprint, - unsigned testDeltaNum, bool testDeltaXaxis, bool testCollision, bool testMaxColl, bool testDist, - bool testHighBits, bool testLowBits, bool verbose, bool drawDiagram ) { + unsigned testDeltaNum, flags_t testFlags, flags_t reportFlags ) { std::vector hashidxs; bool result = true; - if (testCollision) { - result &= TestCollisions(hashes, hashidxs, logpSumPtr, keyprint, testDeltaNum, testDeltaXaxis, - testMaxColl, testDist, testHighBits, testLowBits, verbose, drawDiagram); + if (TEST(COLLISIONS, testFlags)) { + result &= TestCollisions(hashes, hashidxs, logpSumPtr, keyprint, testDeltaNum, testFlags, reportFlags); } - if (testDist) { - result &= TestDistribution(hashes, hashidxs, logpSumPtr, keyprint, testDeltaNum, testDeltaXaxis, - verbose, drawDiagram); + if (TEST(DISTRIBUTION, testFlags)) { + result &= TestDistribution(hashes, hashidxs, logpSumPtr, keyprint, testDeltaNum, testFlags, reportFlags); } return result; @@ -838,9 +840,8 @@ static bool TestHashListSingle( std::vector & hashes, int * logpSumPtr // NB: This function is not intended to be used directly; see // TestHashList() and class TestHashListWrapper in Analyze.h. template -bool TestHashListImpl( std::vector & hashes, int * logpSumPtr, KeyFn keyprint, unsigned testDeltaNum, - bool testCollision, bool testMaxColl, bool testDist, - bool testHighBits, bool testLowBits, bool verbose, bool drawDiagram ) { +bool TestHashListImpl( std::vector & hashes, int * logpSumPtr, KeyFn keyprint, + unsigned testDeltaNum, flags_t testFlags, flags_t reportFlags ) { bool result = true; // If testDeltaNum is 1, then compute the difference between each hash @@ -939,24 +940,23 @@ bool TestHashListImpl( std::vector & hashes, int * logpSumPtr, KeyFn k //---------- - result &= TestHashListSingle(hashes, logpSumPtr, keyprint, 0, false, testCollision, testMaxColl, - testDist, testHighBits, testLowBits, verbose, drawDiagram); + result &= TestHashListSingle(hashes, logpSumPtr, keyprint, 0, testFlags, reportFlags); //---------- if (testDeltaNum > 0) { - if (verbose) { + if (!REPORT(QUIET, reportFlags)) { printf("---Analyzing differential distribution\n"); } - result &= TestHashListSingle(hashdeltas_x, logpSumPtr, keyprint, testDeltaNum, true, testCollision, - testMaxColl, testDist, testHighBits, testLowBits, verbose, drawDiagram); + result &= TestHashListSingle(hashdeltas_x, logpSumPtr, keyprint, testDeltaNum, + testFlags | FLAG_TEST_DELTAXAXIS, reportFlags); if (testDeltaNum > 2) { - if (verbose) { + if (!REPORT(QUIET, reportFlags)) { printf("---Analyzing additional differential distribution\n"); } - result &= TestHashListSingle(hashdeltas_y, logpSumPtr, keyprint, testDeltaNum, false, testCollision, - testMaxColl, testDist, testHighBits, testLowBits, verbose, drawDiagram); + result &= TestHashListSingle(hashdeltas_y, logpSumPtr, keyprint, testDeltaNum, + testFlags, reportFlags); } } diff --git a/util/Analyze.h b/util/Analyze.h index 35da9b57..b5d192d3 100644 --- a/util/Analyze.h +++ b/util/Analyze.h @@ -59,11 +59,18 @@ hidx_t FindCollisionsIndices( std::vector & hashes, std::map & hashidxs ); //----------------------------------------------------------------------------- -// This is not intended to be used directly; see below +// These is not intended to be used directly; see below template -bool TestHashListImpl( std::vector & hashes, int * logpSumPtr, KeyFn keyprint, unsigned testDeltaNum, - bool testCollision, bool testMaxColl, bool testDist, bool testHighBits, bool testLowBits, - bool verbose, bool drawDiagram ); +bool TestHashListImpl( std::vector & hashes, int * logpSumPtr, KeyFn keyprint, + unsigned testDeltaNum, flags_t testFlags, flags_t reportFlags ); + +#define TEST(flagname, var) (!!(var & FLAG_TEST_ ## flagname)) +#define FLAG_TEST_COLLISIONS (1 << 0) +#define FLAG_TEST_MAXCOLLISIONS (1 << 1) +#define FLAG_TEST_DISTRIBUTION (1 << 2) +#define FLAG_TEST_HIGHBITS (1 << 3) +#define FLAG_TEST_LOWBITS (1 << 4) +#define FLAG_TEST_DELTAXAXIS (1 << 5) // This provides a user-friendly wrapper to TestHashListImpl<>() by using // the Named Parameter Idiom. @@ -79,20 +86,19 @@ class TestHashListWrapper { unsigned deltaNum_; int * logpSumPtr_; KeyFn keyPrint_; + flags_t reportFlags_; bool testCollisions_; bool testMaxCollisions_; bool testDistribution_; bool testHighBits_; bool testLowBits_; - bool verbose_; - bool drawDiagram_; + bool quietMode_; public: inline TestHashListWrapper( std::vector & hashes ) : - hashes_( hashes ), deltaNum_( 0 ), logpSumPtr_( NULL ), keyPrint_( NULL ), + hashes_( hashes ), deltaNum_( 0 ), logpSumPtr_( NULL ), keyPrint_( NULL ), reportFlags_( 0 ), testCollisions_( true ), testMaxCollisions_( false ), testDistribution_( true ), - testHighBits_( true ), testLowBits_( true ), - verbose_( true ), drawDiagram_( false ) {} + testHighBits_( true ), testLowBits_( true ), quietMode_( false ) {} inline TestHashListWrapper & sumLogp( int * p ) { logpSumPtr_ = p; return *this; } @@ -110,17 +116,24 @@ class TestHashListWrapper { inline TestHashListWrapper & dumpFailKeys( KeyFn p ) { keyPrint_ = std::move(p); return *this; } - inline TestHashListWrapper & verbose( bool s ) { verbose_ = s; return *this; } + inline TestHashListWrapper & quiet( bool s ) { quietMode_ = s; return *this; } - inline TestHashListWrapper & drawDiagram( bool s ) { drawDiagram_ = s; return *this; } + inline TestHashListWrapper & reportFlags( flags_t f ) { reportFlags_ = f; return *this; } // This can't be explicit, because we want code like // "bool result = TestHashList()" to Just Work(tm), // even if that allows other, nonsensical uses of TestHashList(). inline operator bool () const { + flags_t testFlags_ = 0; + + if (testCollisions_) { testFlags_ |= FLAG_TEST_COLLISIONS; } + if (testMaxCollisions_) { testFlags_ |= FLAG_TEST_MAXCOLLISIONS; } + if (testDistribution_) { testFlags_ |= FLAG_TEST_DISTRIBUTION; } + if (testHighBits_) { testFlags_ |= FLAG_TEST_HIGHBITS; } + if (testLowBits_) { testFlags_ |= FLAG_TEST_LOWBITS; } + return TestHashListImpl(hashes_, logpSumPtr_, keyPrint_, deltaNum_, - testCollisions_, testMaxCollisions_, testDistribution_, - testHighBits_, testLowBits_, verbose_, drawDiagram_); + testFlags_, quietMode_ ? FLAG_REPORT_QUIET : reportFlags_); } }; // class TestHashListWrapper diff --git a/util/Reporting.cpp b/util/Reporting.cpp index fae18bc7..11f3b24b 100644 --- a/util/Reporting.cpp +++ b/util/Reporting.cpp @@ -316,7 +316,7 @@ static void plot( const double p_value, const size_t trials ) { // (number of excess "heads" or "tails") over all those trials was the // specified worstbiascnt. bool ReportBias( const uint32_t * counts, const int coinflips, const int trials, - const int hashbits, const bool drawDiagram ) { + const int hashbits, const flags_t flags ) { const int expected = coinflips / 2; int worstbias = 0; int worstbiasN = 0; @@ -347,7 +347,7 @@ bool ReportBias( const uint32_t * counts, const int coinflips, const int trials, bool result = true; recordLog2PValue(logp_value); - if (drawDiagram) { + if (REPORT(DIAGRAMS, flags)) { if (p_value > 0.00001) { printf("max is %5.*f%% at bit %4d -> out %3d (%6d) (p<%8.6f) (^%2d)", pctdigits, pct, worstbiasKeybit, worstbiasHashbit, worstbias, p_value, logp_value); @@ -369,7 +369,7 @@ bool ReportBias( const uint32_t * counts, const int coinflips, const int trials, printf("\n"); } - if (drawDiagram) { + if (REPORT(DIAGRAMS, flags)) { printf("["); for (int i = 0; i < trials; i++) { int thisbias = abs((int)counts[i] - expected); @@ -389,7 +389,7 @@ bool ReportBias( const uint32_t * counts, const int coinflips, const int trials, // we convert from the popcount[] and andcount[] arrays into full 2x2 contingency // tables, see the comment in tests/BitIndependence.cpp. bool ReportChiSqIndep( const uint32_t * popcount, const uint32_t * andcount, size_t keybits, - size_t hashbits, size_t testcount, bool drawDiagram ) { + size_t hashbits, size_t testcount, const flags_t flags ) { const size_t hashbitpairs = hashbits / 2 * hashbits; const size_t realhashbitpairs = hashbits / 2 * (hashbits - 1); @@ -456,7 +456,7 @@ bool ReportChiSqIndep( const uint32_t * popcount, const uint32_t * andcount, siz // andcount arrays in linear order. But for human-oriented printouts, we want to // iterate over them differently, and so reporting is now done here in its own // loop, separate from analysis. - if (drawDiagram) { + if (REPORT(DIAGRAMS, flags)) { size_t xyoffset = 0; for (size_t out1 = 0; out1 < hashbits - 1; out1++) { for (size_t out2 = out1 + 1; out2 < hashbits; out2++) { @@ -491,7 +491,7 @@ bool ReportChiSqIndep( const uint32_t * popcount, const uint32_t * andcount, siz //----------------------------------------------------------------------------- bool ReportCollisions( uint64_t const nbH, int collcount, unsigned hashsize, int * logpp, - bool maxcoll, bool highbits, bool header, bool verbose, bool drawDiagram ) { + bool maxcoll, bool highbits, bool header, const flags_t flags ) { bool largehash = hashsize > (8 * sizeof(uint32_t)); // The expected number depends on what collision statistic is being @@ -564,7 +564,7 @@ bool ReportCollisions( uint64_t const nbH, int collcount, unsigned hashsize, int recordLog2PValue(logp_value); - if (verbose) { + if (!REPORT(QUIET, flags)) { if (header) { printf("Testing %s collisions (%s %3i-bit)", maxcoll ? "max" : "all", highbits ? "high" : "low ", hashsize); } @@ -584,7 +584,7 @@ bool ReportCollisions( uint64_t const nbH, int collcount, unsigned hashsize, int // and deltas and exact p-values add visual noise and variable line // widths and possibly field counts, they are now only printed out // in --verbose mode. - if (drawDiagram) { + if (REPORT(DIAGRAMS, flags)) { if (p_value > 0.00001) { printf("(%+i) (p<%8.6f) (^%2d)", collcount - (int)round(expected), p_value, logp_value); } else { @@ -608,11 +608,11 @@ bool ReportCollisions( uint64_t const nbH, int collcount, unsigned hashsize, int //----------------------------------------------------------------------------- bool ReportBitsCollisions( uint64_t nbH, const int * collcounts, int minBits, int maxBits, - int * logpp, int * maxbitsp, bool highbits, bool verbose, bool drawDiagram ) { + int * logpp, int * maxbitsp, bool highbits, const flags_t flags ) { if ((maxBits <= 1) || (minBits > maxBits)) { return true; } int spacelen = 80; - if (verbose) { + if (!REPORT(QUIET, flags)) { spacelen -= printf("Testing all collisions (%s %2i..%2i bits) - ", highbits ? "high" : "low ", minBits, maxBits); } @@ -658,7 +658,7 @@ bool ReportBitsCollisions( uint64_t nbH, const int * collcounts, int minBits, in warning = true; } - if (verbose) { + if (!REPORT(QUIET, flags)) { int i_maxCollDevExp = (int)round(maxCollDevExp); spacelen -= printf("Worst is %2i bits: %i/%i ", maxCollDevBits, maxCollDevNb, i_maxCollDevExp); if (spacelen < 0) { @@ -677,7 +677,7 @@ bool ReportBitsCollisions( uint64_t nbH, const int * collcounts, int minBits, in printf("%.*s(%#.4gx) ", spacelen, g_manyspaces, maxCollDev); } - if (drawDiagram) { + if (REPORT(DIAGRAMS, flags)) { if (p_value > 0.00001) { printf("(%+i) (p<%8.6f) (^%2d)", maxCollDevNb - i_maxCollDevExp, p_value, logp_value); } else { @@ -701,7 +701,7 @@ bool ReportBitsCollisions( uint64_t nbH, const int * collcounts, int minBits, in //----------------------------------------------------------------------------- bool ReportDistribution( const std::vector & scores, int tests, int hashbits, int maxwidth, int minwidth, - int * logpp, int * worstStartp, int * worstWidthp, bool verbose, bool drawDiagram ) { + int * logpp, int * worstStartp, int * worstWidthp, const flags_t flags ) { // Find the startbit with the worst bias. Only report on biases above 0. double worstN = 0; int worstStart = -1; @@ -712,7 +712,7 @@ bool ReportDistribution( const std::vector & scores, int tests, int hash for (int width = maxwidth; width >= minwidth; width--) { double n = *worstptr++; - if (drawDiagram) { plot(GetStdNormalPValue(n), tests); } + if (REPORT(DIAGRAMS, flags)) { plot(GetStdNormalPValue(n), tests); } if (worstN <= n) { worstN = n; @@ -721,7 +721,7 @@ bool ReportDistribution( const std::vector & scores, int tests, int hash } } - if (drawDiagram) { printf("]\n%s", ((startbit + 1) == hashbits) ? "" : "["); } + if (REPORT(DIAGRAMS, flags)) { printf("]\n%s", ((startbit + 1) == hashbits) ? "" : "["); } } addVCodeResult((uint32_t)worstN); @@ -750,7 +750,7 @@ bool ReportDistribution( const std::vector & scores, int tests, int hash warning = true; } - if (verbose) { + if (!REPORT(QUIET, flags)) { if (worstStart == -1) { printf("No positive bias detected %5.3fx ", 0.0); } else if (mult < 9.0) { @@ -759,7 +759,7 @@ bool ReportDistribution( const std::vector & scores, int tests, int hash printf("Worst bias is %2d bits at bit %3d: %#.4gx ", worstWidth, worstStart, mult); } - if (drawDiagram) { + if (REPORT(DIAGRAMS, flags)) { if (p_value > 0.00001) { printf("(%f) (p<%8.6f) (^%2d)", worstN, p_value, logp_value); } else { diff --git a/util/Reporting.h b/util/Reporting.h index b5aed7c3..440af230 100644 --- a/util/Reporting.h +++ b/util/Reporting.h @@ -62,16 +62,16 @@ void ShowOutliers( const std::vector & hashes, const std::vector & score, int tests, int hashbits, int maxwidth, int minwidth, - int * logpp, int * worstStartp, int * worstWidthp, bool verbose, bool drawDiagram ); + int * logpp, int * worstStartp, int * worstWidthp, const flags_t flags ); diff --git a/util/TestGlobals.h b/util/TestGlobals.h index 01f688f8..8a4be4f2 100644 --- a/util/TestGlobals.h +++ b/util/TestGlobals.h @@ -57,6 +57,18 @@ extern const char * g_manyspaces; extern HashInfo::endianness g_hashEndian; #endif +//----------------------------------------------------------------------------- +// Verbosity flags + +typedef uint32_t flags_t; + +#define REPORT(flagname, var) (!!(var & FLAG_REPORT_ ## flagname)) + +#define FLAG_REPORT_QUIET (1 << 0) +#define FLAG_REPORT_VERBOSE (1 << 1) +#define FLAG_REPORT_DIAGRAMS (1 << 2) +#define FLAG_REPORT_PROGRESS (1 << 3) + //----------------------------------------------------------------------------- // Recording test results for final summary printout