mirror of
https://github.com/bkaradzic/bx.git
synced 2026-02-17 20:52:37 +01:00
97 lines
1.7 KiB
C++
97 lines
1.7 KiB
C++
/*
|
|
* Copyright 2010-2011 Branimir Karadzic. All rights reserved.
|
|
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
|
*/
|
|
|
|
#ifndef __BX_HASH_H__
|
|
#define __BX_HASH_H__
|
|
|
|
#include "bx.h"
|
|
|
|
namespace bx
|
|
{
|
|
// MurmurHash2 was written by Austin Appleby, and is placed in the public
|
|
// domain. The author hereby disclaims copyright to this source code.
|
|
#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; }
|
|
|
|
class HashMurmur2A
|
|
{
|
|
public:
|
|
void begin(uint32_t _seed = 0)
|
|
{
|
|
m_hash = _seed;
|
|
m_tail = 0;
|
|
m_count = 0;
|
|
m_size = 0;
|
|
}
|
|
|
|
void add(const void* _data, int _len)
|
|
{
|
|
const uint8_t* data = (uint8_t*)_data;
|
|
m_size += _len;
|
|
|
|
mixTail(data, _len);
|
|
|
|
while(_len >= 4)
|
|
{
|
|
uint32_t kk = *(uint32_t*)data;
|
|
|
|
mmix(m_hash, kk);
|
|
|
|
data += 4;
|
|
_len -= 4;
|
|
}
|
|
|
|
mixTail(data, _len);
|
|
}
|
|
|
|
template<typename Ty>
|
|
void add(Ty _value)
|
|
{
|
|
add(&_value, sizeof(Ty) );
|
|
}
|
|
|
|
uint32_t 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;
|
|
}
|
|
|
|
private:
|
|
void mixTail(const uint8_t*& _data, int& _len)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint32_t m_hash;
|
|
uint32_t m_tail;
|
|
uint32_t m_count;
|
|
uint32_t m_size;
|
|
};
|
|
|
|
} // namespace bx
|
|
|
|
#endif // __BX_HASH_H__
|