From e0e12debf82124012ba84e13fe6662c812bba8b1 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Mon, 8 Jul 2013 10:47:57 -0700 Subject: Fix murmur hash implementations to work on strict alignment architectures like OpenBSD/mips64el and OpenBSD/hppa64. --- src/build_log.cc | 25 +++++++++++++------------ src/hash_map.h | 4 +++- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/build_log.cc b/src/build_log.cc index 6b73002..a040ce2 100644 --- a/src/build_log.cc +++ b/src/build_log.cc @@ -54,26 +54,27 @@ uint64_t MurmurHash64A(const void* key, size_t len) { const uint64_t m = BIG_CONSTANT(0xc6a4a7935bd1e995); const int r = 47; uint64_t h = seed ^ (len * m); - const uint64_t * data = (const uint64_t *)key; - const uint64_t * end = data + (len/8); - while (data != end) { - uint64_t k = *data++; + const unsigned char * data = (const unsigned char *)key; + while (len >= 8) { + uint64_t k; + memcpy(&k, data, sizeof k); k *= m; k ^= k >> r; k *= m; h ^= k; h *= m; + data += 8; + len -= 8; } - const unsigned char* data2 = (const unsigned char*)data; switch (len & 7) { - case 7: h ^= uint64_t(data2[6]) << 48; - case 6: h ^= uint64_t(data2[5]) << 40; - case 5: h ^= uint64_t(data2[4]) << 32; - case 4: h ^= uint64_t(data2[3]) << 24; - case 3: h ^= uint64_t(data2[2]) << 16; - case 2: h ^= uint64_t(data2[1]) << 8; - case 1: h ^= uint64_t(data2[0]); + case 7: h ^= uint64_t(data[6]) << 48; + case 6: h ^= uint64_t(data[5]) << 40; + case 5: h ^= uint64_t(data[4]) << 32; + case 4: h ^= uint64_t(data[3]) << 24; + case 3: h ^= uint64_t(data[2]) << 16; + case 2: h ^= uint64_t(data[1]) << 8; + case 1: h ^= uint64_t(data[0]); h *= m; }; h ^= h >> r; diff --git a/src/hash_map.h b/src/hash_map.h index 076f6c0..919b6fc 100644 --- a/src/hash_map.h +++ b/src/hash_map.h @@ -15,6 +15,7 @@ #ifndef NINJA_MAP_H_ #define NINJA_MAP_H_ +#include #include "string_piece.h" // MurmurHash2, by Austin Appleby @@ -26,7 +27,8 @@ unsigned int MurmurHash2(const void* key, size_t len) { unsigned int h = seed ^ len; const unsigned char * data = (const unsigned char *)key; while (len >= 4) { - unsigned int k = *(unsigned int *)data; + unsigned int k; + memcpy(&k, data, sizeof k); k *= m; k ^= k >> r; k *= m; -- cgit v0.12