src/core/model/hash-murmur3.cc
changeset 10189 9b6d0037b360
parent 10145 f14c652ad233
child 10411 f5916669dbe7
equal deleted inserted replaced
10188:f2177f4b2cb1 10189:9b6d0037b360
    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