Changeset View
Changeset View
Standalone View
Standalone View
src/hash.cpp
Show All 11 Lines | inline uint32_t ROTL32(uint32_t x, int8_t r) { | ||||
return (x << r) | (x >> (32 - r)); | return (x << r) | (x >> (32 - r)); | ||||
} | } | ||||
uint32_t MurmurHash3(uint32_t nHashSeed, | uint32_t MurmurHash3(uint32_t nHashSeed, | ||||
const std::vector<uint8_t> &vDataToHash) { | const std::vector<uint8_t> &vDataToHash) { | ||||
// The following is MurmurHash3 (x86_32), see | // The following is MurmurHash3 (x86_32), see | ||||
// http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp | // http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp | ||||
uint32_t h1 = nHashSeed; | uint32_t h1 = nHashSeed; | ||||
if (vDataToHash.size() > 0) { | |||||
const uint32_t c1 = 0xcc9e2d51; | const uint32_t c1 = 0xcc9e2d51; | ||||
const uint32_t c2 = 0x1b873593; | const uint32_t c2 = 0x1b873593; | ||||
const int nblocks = vDataToHash.size() / 4; | const int nblocks = vDataToHash.size() / 4; | ||||
//---------- | //---------- | ||||
// body | // body | ||||
const uint8_t *blocks = &vDataToHash[0] + nblocks * 4; | const uint8_t *blocks = vDataToHash.data(); | ||||
for (int i = -nblocks; i; i++) { | for (int i = 0; i < nblocks; ++i) { | ||||
uint32_t k1 = ReadLE32(blocks + i * 4); | uint32_t k1 = ReadLE32(blocks + i * 4); | ||||
k1 *= c1; | k1 *= c1; | ||||
k1 = ROTL32(k1, 15); | k1 = ROTL32(k1, 15); | ||||
k1 *= c2; | k1 *= c2; | ||||
h1 ^= k1; | h1 ^= k1; | ||||
h1 = ROTL32(h1, 13); | h1 = ROTL32(h1, 13); | ||||
h1 = h1 * 5 + 0xe6546b64; | h1 = h1 * 5 + 0xe6546b64; | ||||
} | } | ||||
//---------- | //---------- | ||||
// tail | // tail | ||||
const uint8_t *tail = (const uint8_t *)(&vDataToHash[0] + nblocks * 4); | const uint8_t *tail = vDataToHash.data() + nblocks * 4; | ||||
uint32_t k1 = 0; | uint32_t k1 = 0; | ||||
switch (vDataToHash.size() & 3) { | switch (vDataToHash.size() & 3) { | ||||
case 3: | case 3: | ||||
k1 ^= tail[2] << 16; | k1 ^= tail[2] << 16; | ||||
// FALLTHROUGH | // FALLTHROUGH | ||||
case 2: | case 2: | ||||
k1 ^= tail[1] << 8; | k1 ^= tail[1] << 8; | ||||
// FALLTHROUGH | // FALLTHROUGH | ||||
case 1: | case 1: | ||||
k1 ^= tail[0]; | k1 ^= tail[0]; | ||||
k1 *= c1; | k1 *= c1; | ||||
k1 = ROTL32(k1, 15); | k1 = ROTL32(k1, 15); | ||||
k1 *= c2; | k1 *= c2; | ||||
h1 ^= k1; | h1 ^= k1; | ||||
} | } | ||||
} | |||||
//---------- | //---------- | ||||
// finalization | // finalization | ||||
h1 ^= vDataToHash.size(); | h1 ^= vDataToHash.size(); | ||||
h1 ^= h1 >> 16; | h1 ^= h1 >> 16; | ||||
h1 *= 0x85ebca6b; | h1 *= 0x85ebca6b; | ||||
h1 ^= h1 >> 13; | h1 ^= h1 >> 13; | ||||
h1 *= 0xc2b2ae35; | h1 *= 0xc2b2ae35; | ||||
Show All 18 Lines |