-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathmurmur2A.h
113 lines (88 loc) · 2.22 KB
/
murmur2A.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//------------------------------- murmur2A.h -----------------------------------
//
// This software is in the public domain. The only restriction on its use is
// that no one can remove it from the public domain by claiming ownership of it,
// including the original authors.
//
// There is no warranty of correctness on the software contained herein. Use
// at your own risk.
//
//------------------------------------------------------------------------------
#ifndef MURMUR2A_H
#define MURMUR2A_H
#include <cstddef>
// namespace acme is used to demonstrate example code. It is not proposed.
namespace acme
{
class MurmurHash2A
{
unsigned int m_hash;
unsigned int m_tail;
unsigned int m_count;
unsigned int m_size;
public:
using result_type = unsigned int;
MurmurHash2A ( unsigned int seed = 0 ) noexcept
: m_hash{seed}
, m_tail{0}
, m_count{0}
, m_size{0}
{
}
void
operator() ( const void* p, std::size_t len ) noexcept
{
const unsigned char* data = static_cast<const unsigned char*>(p);
m_size += len;
MixTail(data,len);
while(len >= 4)
{
unsigned int k = *(unsigned int*)data;
mmix(m_hash,k);
data += 4;
len -= 4;
}
MixTail(data,len);
}
explicit
operator result_type () noexcept
{
mmix(m_hash,m_tail);
mmix(m_hash,m_size);
m_hash ^= m_hash >> 13;
m_hash *= m;
m_hash ^= m_hash >> 15;
return m_hash;
}
private:
static const unsigned int m = 0x5bd1e995;
static const int r = 24;
static
void
mmix(unsigned int& h, unsigned int& k) noexcept
{
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
}
void
MixTail ( const unsigned char * & data, std::size_t & len ) noexcept
{
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;
}
}
}
};
} // acme
#endif // MURMUR2A_H