murmurhash.c revision 1.2
1/* $NetBSD: murmurhash.c,v 1.2 2012/07/08 13:42:29 rmind Exp $ */ 2 3/* 4 * MurmurHash2 -- from the original code: 5 * 6 * "MurmurHash2 was written by Austin Appleby, and is placed in the public 7 * domain. The author hereby disclaims copyright to this source code." 8 * 9 * References: 10 * http://code.google.com/p/smhasher/ 11 * https://sites.google.com/site/murmurhash/ 12 */ 13 14#include <sys/cdefs.h> 15#include <sys/types.h> 16#include <sys/hash.h> 17 18#if defined(_KERNEL) || defined(_STANDALONE) 19__KERNEL_RCSID(0, "$NetBSD: murmurhash.c,v 1.2 2012/07/08 13:42:29 rmind Exp $"); 20#else 21__RCSID("$NetBSD: murmurhash.c,v 1.2 2012/07/08 13:42:29 rmind Exp $"); 22#endif 23 24uint32_t 25murmurhash2(const void *key, size_t len, uint32_t seed) 26{ 27 /* 28 * Note: 'm' and 'r' are mixing constants generated offline. 29 * They're not really 'magic', they just happen to work well. 30 * Initialize the hash to a 'random' value. 31 */ 32 const uint32_t m = 0x5bd1e995; 33 const int r = 24; 34 35 const uint8_t *data = (const uint8_t *)key; 36 uint32_t h = seed ^ (uint32_t)len; 37 38 while (len >= sizeof(uint32_t)) { 39 uint32_t k; 40 41 k = data[0]; 42 k |= data[1] << 8; 43 k |= data[2] << 16; 44 k |= data[3] << 24; 45 46 k *= m; 47 k ^= k >> r; 48 k *= m; 49 50 h *= m; 51 h ^= k; 52 53 data += sizeof(uint32_t); 54 len -= sizeof(uint32_t); 55 } 56 57 /* Handle the last few bytes of the input array. */ 58 switch (len) { 59 case 3: 60 h ^= data[2] << 16; 61 /* FALLTHROUGH */ 62 case 2: 63 h ^= data[1] << 8; 64 /* FALLTHROUGH */ 65 case 1: 66 h ^= data[0]; 67 h *= m; 68 } 69 70 /* 71 * Do a few final mixes of the hash to ensure the last few 72 * bytes are well-incorporated. 73 */ 74 h ^= h >> 13; 75 h *= m; 76 h ^= h >> 15; 77 78 return h; 79} 80