/* +----------------------------------------------------------------------+ | HipHop for PHP | +----------------------------------------------------------------------+ | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) | | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ */ /** * This file contains code from MurmurHash, by Austin Appleby. The licensing * information for MurmurHash as specified on its website, * http://sites.google.com/site/murmurhash/, is as follows: "For business * purposes, Murmurhash is under the MIT license. */ #include #include #include "hphp/runtime/ext/hash/hash_murmur.h" namespace HPHP { /** * MurmurHash2, 64-bit versions, by Austin Appleby * * The same caveats as 32-bit MurmurHash2 apply here - beware of alignment * and endian-ness issues if used across multiple platforms. * * 64-bit hash for 64-bit platforms */ uint64_t murmur_hash_64A(const void* const key, const size_t len, const uint32_t seed) { const uint64_t m = 0xc6a4a7935bd1e995ULL; const int r = 47; uint64_t h = seed ^ (len * m); const uint64_t * data = (const uint64_t *)key; const uint64_t * end = data + (len/8); while(data != end) { uint64_t k = *data++; k *= m; k ^= k >> r; k *= m; h ^= k; h *= m; } const uint8_t * data2 = (const uint8_t*)data; switch(len & 7) { case 7: h ^= (uint64_t)data2[6] << 48; case 6: h ^= (uint64_t)data2[5] << 40; case 5: h ^= (uint64_t)data2[4] << 32; case 4: h ^= (uint64_t)data2[3] << 24; case 3: h ^= (uint64_t)data2[2] << 16; case 2: h ^= (uint64_t)data2[1] << 8; case 1: h ^= (uint64_t)data2[0]; h *= m; }; h ^= h >> r; h *= m; h ^= h >> r; return h; } /* MurmurHash64A performance-optimized for hash of uint64_t keys and seed = M0 */ uint64_t murmur_rehash_64A(uint64_t k) { const uint64_t m = 0xc6a4a7935bd1e995ULL; const int r = 47; uint64_t h = (uint64_t)SEED ^ (sizeof(uint64_t) * m); k *= m; k ^= k >> r; k *= m; h ^= k; h *= m; h ^= h >> r; h *= m; h ^= h >> r; return h; } }