|
@@ -9,171 +9,89 @@
|
|
|
|
|
|
|
|
namespace bx
|
|
namespace bx
|
|
|
{
|
|
{
|
|
|
-#define MURMUR_M 0x5bd1e995
|
|
|
|
|
-#define MURMUR_R 24
|
|
|
|
|
-#define mmix(_h, _k) { _k *= MURMUR_M; _k ^= _k >> MURMUR_R; _k *= MURMUR_M; _h *= MURMUR_M; _h ^= _k; }
|
|
|
|
|
-
|
|
|
|
|
- inline void HashMurmur2A::begin(uint32_t _seed)
|
|
|
|
|
|
|
+ inline void HashAdler32::begin()
|
|
|
{
|
|
{
|
|
|
- m_hash = _seed;
|
|
|
|
|
- m_tail = 0;
|
|
|
|
|
- m_count = 0;
|
|
|
|
|
- m_size = 0;
|
|
|
|
|
|
|
+ m_a = 1;
|
|
|
|
|
+ m_b = 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- inline void HashMurmur2A::add(const void* _data, int _len)
|
|
|
|
|
|
|
+ inline void HashAdler32::add(const void* _data, int32_t _len)
|
|
|
{
|
|
{
|
|
|
- if (BX_UNLIKELY(!isAligned(_data, 4) ) )
|
|
|
|
|
- {
|
|
|
|
|
- addUnaligned(_data, _len);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- addAligned(_data, _len);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ constexpr uint32_t kModAdler = 65521;
|
|
|
|
|
|
|
|
- inline void HashMurmur2A::addAligned(const void* _data, int _len)
|
|
|
|
|
- {
|
|
|
|
|
const uint8_t* data = (const uint8_t*)_data;
|
|
const uint8_t* data = (const uint8_t*)_data;
|
|
|
- m_size += _len;
|
|
|
|
|
-
|
|
|
|
|
- mixTail(data, _len);
|
|
|
|
|
-
|
|
|
|
|
- while(_len >= 4)
|
|
|
|
|
|
|
+ for (; _len != 0; --_len)
|
|
|
{
|
|
{
|
|
|
- uint32_t kk = *(uint32_t*)data;
|
|
|
|
|
-
|
|
|
|
|
- mmix(m_hash, kk);
|
|
|
|
|
-
|
|
|
|
|
- data += 4;
|
|
|
|
|
- _len -= 4;
|
|
|
|
|
|
|
+ m_a = (m_a + *data++) % kModAdler;
|
|
|
|
|
+ m_b = (m_b + m_a ) % kModAdler;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- mixTail(data, _len);
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- inline void HashMurmur2A::addUnaligned(const void* _data, int _len)
|
|
|
|
|
|
|
+ inline void HashAdler32::add(const char* _data)
|
|
|
{
|
|
{
|
|
|
- const uint8_t* data = (const uint8_t*)_data;
|
|
|
|
|
- m_size += _len;
|
|
|
|
|
-
|
|
|
|
|
- mixTail(data, _len);
|
|
|
|
|
-
|
|
|
|
|
- while(_len >= 4)
|
|
|
|
|
- {
|
|
|
|
|
- uint32_t kk;
|
|
|
|
|
- readUnaligned(data, kk);
|
|
|
|
|
-
|
|
|
|
|
- mmix(m_hash, kk);
|
|
|
|
|
-
|
|
|
|
|
- data += 4;
|
|
|
|
|
- _len -= 4;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return add(StringView(_data) );
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- mixTail(data, _len);
|
|
|
|
|
|
|
+ inline void HashAdler32::add(const StringView& _data)
|
|
|
|
|
+ {
|
|
|
|
|
+ return add(_data.getPtr(), _data.getLength() );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
template<typename Ty>
|
|
template<typename Ty>
|
|
|
- inline void HashMurmur2A::add(Ty _value)
|
|
|
|
|
|
|
+ inline void HashAdler32::add(const Ty& _data)
|
|
|
{
|
|
{
|
|
|
- add(&_value, sizeof(Ty) );
|
|
|
|
|
|
|
+ add(&_data, sizeof(Ty) );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- inline uint32_t HashMurmur2A::end()
|
|
|
|
|
|
|
+ inline uint32_t HashAdler32::end()
|
|
|
{
|
|
{
|
|
|
- mmix(m_hash, m_tail);
|
|
|
|
|
- mmix(m_hash, m_size);
|
|
|
|
|
-
|
|
|
|
|
- m_hash ^= m_hash >> 13;
|
|
|
|
|
- m_hash *= MURMUR_M;
|
|
|
|
|
- m_hash ^= m_hash >> 15;
|
|
|
|
|
-
|
|
|
|
|
- return m_hash;
|
|
|
|
|
|
|
+ return m_a | (m_b<<16);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- inline void HashMurmur2A::readUnaligned(const void* _data, uint32_t& _out)
|
|
|
|
|
|
|
+ inline void HashCrc32::add(const char* _data)
|
|
|
{
|
|
{
|
|
|
- const uint8_t* data = (const uint8_t*)_data;
|
|
|
|
|
- if (BX_ENABLED(BX_CPU_ENDIAN_BIG) )
|
|
|
|
|
- {
|
|
|
|
|
- _out = 0
|
|
|
|
|
- | data[0]<<24
|
|
|
|
|
- | data[1]<<16
|
|
|
|
|
- | data[2]<<8
|
|
|
|
|
- | data[3]
|
|
|
|
|
- ;
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- _out = 0
|
|
|
|
|
- | data[0]
|
|
|
|
|
- | data[1]<<8
|
|
|
|
|
- | data[2]<<16
|
|
|
|
|
- | data[3]<<24
|
|
|
|
|
- ;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return add(StringView(_data) );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- inline void HashMurmur2A::mixTail(const uint8_t*& _data, int& _len)
|
|
|
|
|
|
|
+ inline void HashCrc32::add(const StringView& _data)
|
|
|
{
|
|
{
|
|
|
- while( _len && ((_len<4) || m_count) )
|
|
|
|
|
- {
|
|
|
|
|
- m_tail |= (*_data++) << (m_count * 8);
|
|
|
|
|
-
|
|
|
|
|
- m_count++;
|
|
|
|
|
- _len--;
|
|
|
|
|
-
|
|
|
|
|
- if(m_count == 4)
|
|
|
|
|
- {
|
|
|
|
|
- mmix(m_hash, m_tail);
|
|
|
|
|
- m_tail = 0;
|
|
|
|
|
- m_count = 0;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return add(_data.getPtr(), _data.getLength() );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-#undef MURMUR_M
|
|
|
|
|
-#undef MURMUR_R
|
|
|
|
|
-#undef mmix
|
|
|
|
|
-
|
|
|
|
|
- inline void HashAdler32::begin()
|
|
|
|
|
|
|
+ template<typename Ty>
|
|
|
|
|
+ inline void HashCrc32::add(const Ty& _data)
|
|
|
{
|
|
{
|
|
|
- m_a = 1;
|
|
|
|
|
- m_b = 0;
|
|
|
|
|
|
|
+ add(&_data, sizeof(Ty) );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- inline void HashAdler32::add(const void* _data, int _len)
|
|
|
|
|
|
|
+ inline uint32_t HashCrc32::end()
|
|
|
{
|
|
{
|
|
|
- const uint32_t kModAdler = 65521;
|
|
|
|
|
- const uint8_t* data = (const uint8_t*)_data;
|
|
|
|
|
- for (; _len != 0; --_len)
|
|
|
|
|
- {
|
|
|
|
|
- m_a = (m_a + *data++) % kModAdler;
|
|
|
|
|
- m_b = (m_b + m_a ) % kModAdler;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ m_hash ^= UINT32_MAX;
|
|
|
|
|
+ return m_hash;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- template<typename Ty>
|
|
|
|
|
- inline void HashAdler32::add(Ty _value)
|
|
|
|
|
|
|
+ inline void HashMurmur2A::begin(uint32_t _seed)
|
|
|
{
|
|
{
|
|
|
- add(&_value, sizeof(Ty) );
|
|
|
|
|
|
|
+ m_hash = _seed;
|
|
|
|
|
+ m_tail = 0;
|
|
|
|
|
+ m_count = 0;
|
|
|
|
|
+ m_size = 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- inline uint32_t HashAdler32::end()
|
|
|
|
|
|
|
+ inline void HashMurmur2A::add(const char* _data)
|
|
|
{
|
|
{
|
|
|
- return m_a | (m_b<<16);
|
|
|
|
|
|
|
+ return add(StringView(_data) );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- template<typename Ty>
|
|
|
|
|
- inline void HashCrc32::add(Ty _value)
|
|
|
|
|
|
|
+ inline void HashMurmur2A::add(const StringView& _data)
|
|
|
{
|
|
{
|
|
|
- add(&_value, sizeof(Ty) );
|
|
|
|
|
|
|
+ return add(_data.getPtr(), _data.getLength() );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- inline uint32_t HashCrc32::end()
|
|
|
|
|
|
|
+ template<typename Ty>
|
|
|
|
|
+ inline void HashMurmur2A::add(const Ty& _data)
|
|
|
{
|
|
{
|
|
|
- m_hash ^= UINT32_MAX;
|
|
|
|
|
- return m_hash;
|
|
|
|
|
|
|
+ add(&_data, sizeof(Ty) );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
template<typename HashT>
|
|
template<typename HashT>
|
|
@@ -181,15 +99,14 @@ namespace bx
|
|
|
{
|
|
{
|
|
|
HashT hh;
|
|
HashT hh;
|
|
|
hh.begin();
|
|
hh.begin();
|
|
|
- hh.add(_data, (int)_size);
|
|
|
|
|
|
|
+ hh.add(_data, (int32_t)_size);
|
|
|
return hh.end();
|
|
return hh.end();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- template<typename HashT, typename Ty>
|
|
|
|
|
- inline uint32_t hash(const Ty& _data)
|
|
|
|
|
|
|
+ template<typename HashT>
|
|
|
|
|
+ inline uint32_t hash(const char* _data)
|
|
|
{
|
|
{
|
|
|
- BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
|
|
|
|
|
- return hash<HashT>(&_data, sizeof(Ty) );
|
|
|
|
|
|
|
+ return hash<HashT>(StringView(_data) );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
template<typename HashT>
|
|
template<typename HashT>
|
|
@@ -198,10 +115,11 @@ namespace bx
|
|
|
return hash<HashT>(_data.getPtr(), _data.getLength() );
|
|
return hash<HashT>(_data.getPtr(), _data.getLength() );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- template<typename HashT>
|
|
|
|
|
- inline uint32_t hash(const char* _data)
|
|
|
|
|
|
|
+ template<typename HashT, typename Ty>
|
|
|
|
|
+ inline uint32_t hash(const Ty& _data)
|
|
|
{
|
|
{
|
|
|
- return hash<HashT>(StringView(_data) );
|
|
|
|
|
|
|
+ BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() );
|
|
|
|
|
+ return hash<HashT>(&_data, sizeof(Ty) );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} // namespace bx
|
|
} // namespace bx
|