32 #include "log.h" |
32 #include "log.h" |
33 #include "hash-murmur3.h" |
33 #include "hash-murmur3.h" |
34 |
34 |
35 #include <iomanip> |
35 #include <iomanip> |
36 |
36 |
37 /* |
|
38 * \brief Silence erroneous strict alias warning from a gcc 4.4 bug |
|
39 * |
|
40 * Casting \c (void*) triggers a strict alias warning bug |
|
41 * in gcc 4.4 (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39390). |
|
42 * |
|
43 * In the murmur3 code, data is returned by |
|
44 * \code |
|
45 * void Function (... , void * out) |
|
46 * { |
|
47 * ... |
|
48 * *(uint32_t *)out = ... |
|
49 * } |
|
50 * \endcode |
|
51 * |
|
52 * which triggers the erroneous warning. |
|
53 * |
|
54 * We suppress strict-alias warnings in this compilation unit. |
|
55 * (gcc 4.4 doesn't support the <tt>diagnostic push/pop</tt> pragmas, |
|
56 * so we can't narrow down the suppression any further.) |
|
57 */ |
|
58 // Test for gcc 4.4.x |
|
59 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) |
|
60 #if (GCC_VERSION == 404) |
|
61 # pragma GCC diagnostic ignored "-Wstrict-aliasing" |
|
62 #endif |
|
63 |
|
64 namespace ns3 { |
37 namespace ns3 { |
65 |
38 |
66 NS_LOG_COMPONENT_DEFINE ("Hash-Murmur3"); |
39 NS_LOG_COMPONENT_DEFINE ("Hash-Murmur3"); |
67 |
40 |
68 namespace Hash { |
41 namespace Hash { |
477 uint64_t |
450 uint64_t |
478 Murmur3::GetHash64 (const char * buffer, const size_t size) |
451 Murmur3::GetHash64 (const char * buffer, const size_t size) |
479 { |
452 { |
480 using namespace Murmur3Implementation; |
453 using namespace Murmur3Implementation; |
481 MurmurHash3_x86_128_incr (buffer, size, |
454 MurmurHash3_x86_128_incr (buffer, size, |
482 (uint32_t *)(void *)m_hash64, (void *)(m_hash64)); |
455 (uint32_t *)(void *)m_hash64, m_hash64); |
483 m_size64 += size; |
456 m_size64 += size; |
484 uint64_t hash[2]; |
457 |
|
458 // Simpler would be: |
|
459 // |
|
460 // uint64_t hash[2]; |
|
461 // MurmurHash3_x86_128_fin (m_size64, m_hash64, hash); |
|
462 // return hash[0]; |
|
463 // |
|
464 // but this triggers an aliasing bug in gcc-4.4 (perhaps related to |
|
465 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39390). |
|
466 // In ns-3, this bug produces incorrect results in static optimized |
|
467 // builds only. |
|
468 // |
|
469 // Using uint32_t here avoids the bug, and continues to works with newer gcc. |
|
470 uint32_t hash[4]; |
|
471 |
485 MurmurHash3_x86_128_fin (m_size64, |
472 MurmurHash3_x86_128_fin (m_size64, |
486 (uint32_t*)(void *)m_hash64, (void *)hash); |
473 (uint32_t *)(void *)m_hash64, hash); |
487 return hash[0]; |
474 uint64_t result = hash[1]; |
|
475 result = (result << 32) | hash[0]; |
|
476 return result; |
488 } |
477 } |
489 |
478 |
490 void |
479 void |
491 Murmur3::clear (void) |
480 Murmur3::clear (void) |
492 { |
481 { |
493 m_hash32 = (uint32_t)SEED; |
482 m_hash32 = (uint32_t)SEED; |
494 m_size32 = 0; |
483 m_size32 = 0; |
495 m_hash64[0] = ((uint64_t)(SEED) << 32) + (uint64_t)SEED; |
484 m_hash64[0] = m_hash64[1] = ((uint64_t)(SEED) << 32) + (uint64_t)SEED; |
496 m_hash64[1] = ((uint64_t)(SEED) << 32) + (uint64_t)SEED; |
|
497 m_size64 = 0; |
485 m_size64 = 0; |
498 } |
486 } |
499 |
487 |
500 } // namespace Function |
488 } // namespace Function |
501 |
489 |