blob: ec540186228997808a7c51fc3ecca1fa51eaec09 [file] [log] [blame]
#ifndef FARMHASH_SELF_TEST_GUARD
#define FARMHASH_SELF_TEST_GUARD
#include <cstdio>
#include <iostream>
#include <string.h>
using std::cout;
using std::cerr;
using std::endl;
using std::hex;
static const uint64_t kSeed0 = 1234567;
static const uint64_t kSeed1 = k0;
static const int kDataSize = 1 << 20;
static const int kTestSize = 300;
#define kSeed128 Uint128(kSeed0, kSeed1)
static char data[kDataSize];
static int completed_self_tests = 0;
static int errors = 0;
// Initialize data to pseudorandom values.
void Setup() {
if (completed_self_tests == 0) {
uint64_t a = 9;
uint64_t b = 777;
for (int i = 0; i < kDataSize; i++) {
a += b;
b += a;
a = (a ^ (a >> 41)) * k0;
b = (b ^ (b >> 41)) * k0 + i;
uint8_t u = b >> 37;
memcpy(data + i, &u, 1); // uint8_t -> char
}
}
}
int NoteErrors() {
#define NUM_SELF_TESTS 0
if (++completed_self_tests == NUM_SELF_TESTS)
std::exit(errors > 0);
return errors;
}
template <typename T> inline bool IsNonZero(T x) {
return x != 0;
}
template <> inline bool IsNonZero<uint128_t>(uint128_t x) {
return x != Uint128(0, 0);
}
#endif // FARMHASH_SELF_TEST_GUARD
namespace SKELETON {
uint32_t CreateSeed(int offset, int salt) {
uint32_t h = static_cast<uint32_t>(salt & 0xffffffff);
h = h * c1;
h ^= (h >> 17);
h = h * c1;
h ^= (h >> 17);
h = h * c1;
h ^= (h >> 17);
h += static_cast<uint32_t>(offset & 0xffffffff);
h = h * c1;
h ^= (h >> 17);
h = h * c1;
h ^= (h >> 17);
h = h * c1;
h ^= (h >> 17);
return h;
}
#undef SEED
#undef SEED1
#undef SEED0
#define SEED CreateSeed(offset, -1)
#define SEED0 CreateSeed(offset, 0)
#define SEED1 CreateSeed(offset, 1)
#undef TESTING
#define TESTING 0
#if TESTING
// Return false only if offset is -1 and a spot check of 3 hashes all yield 0.
bool Test(int offset, int len = 0) {
#undef Check
#undef IsAlive
#define Check(x) do { \
const uint32_t actual = (x), e = expected[index++]; \
bool ok = actual == e; \
if (!ok) { \
cerr << "expected " << hex << e << " but got " << actual << endl; \
++errors; \
} \
assert(ok); \
} while (0)
#define IsAlive(x) do { alive += IsNonZero(x); } while (0)
// After the following line is where the uses of "Check" and such will go.
static int index = 0;
return true;
#undef Check
#undef IsAlive
}
int RunTest() {
Setup();
int i = 0;
cout << "Running SKELETON";
if (!Test(-1)) {
cout << "... Unavailable\n";
return NoteErrors();
}
// Good. The function is attempting to hash, so run the full test.
int errors_prior_to_test = errors;
for ( ; i < kTestSize - 1; i++) {
Test(i * i, i);
}
for ( ; i < kDataSize; i += i / 7) {
Test(0, i);
}
Test(0, kDataSize);
cout << (errors == errors_prior_to_test ? "... OK\n" : "... Failed\n");
return NoteErrors();
}
#else
// After the following line is where the code to print hash codes will go.
void Dump(int offset, int len) {
}
#endif
#undef SEED
#undef SEED1
#undef SEED0
} // namespace SKELETON
#if !TESTING
int main(int argc, char** argv) {
Setup();
cout << "uint32_t expected[] = {\n";
int i = 0;
for ( ; i < kTestSize - 1; i++) {
SKELETON::Dump(i * i, i);
}
for ( ; i < kDataSize; i += i / 7) {
SKELETON::Dump(0, i);
}
SKELETON::Dump(0, kDataSize);
cout << "};\n";
}
#endif