murmurhash.c revision 1.1
11.1Srmind/* $NetBSD: murmurhash.c,v 1.1 2012/07/08 01:21:12 rmind Exp $ */ 21.1Srmind 31.1Srmind/* 41.1Srmind * MurmurHash2 -- from the original code: 51.1Srmind * 61.1Srmind * "MurmurHash2 was written by Austin Appleby, and is placed in the public 71.1Srmind * domain. The author hereby disclaims copyright to this source code." 81.1Srmind * 91.1Srmind * References: 101.1Srmind * http://code.google.com/p/smhasher/ 111.1Srmind * https://sites.google.com/site/murmurhash/ 121.1Srmind */ 131.1Srmind 141.1Srmind#include <sys/cdefs.h> 151.1Srmind#include <sys/types.h> 161.1Srmind#include <sys/hash.h> 171.1Srmind 181.1Srmind#if defined(_KERNEL) || defined(_STANDALONE) 191.1Srmind__KERNEL_RCSID(0, "$NetBSD: murmurhash.c,v 1.1 2012/07/08 01:21:12 rmind Exp $"); 201.1Srmind#else 211.1Srmind__RCSID("$NetBSD: murmurhash.c,v 1.1 2012/07/08 01:21:12 rmind Exp $"); 221.1Srmind#endif 231.1Srmind 241.1Srminduint32_t 251.1Srmindmurmurhash2(const void *key, size_t len, uint32_t seed) 261.1Srmind{ 271.1Srmind /* 281.1Srmind * Note: 'm' and 'r' are mixing constants generated offline. 291.1Srmind * They're not really 'magic', they just happen to work well. 301.1Srmind * Initialize the hash to a 'random' value. 311.1Srmind */ 321.1Srmind const uint32_t m = 0x5bd1e995; 331.1Srmind const int r = 24; 341.1Srmind 351.1Srmind const uint8_t *data = (const uint8_t *)key; 361.1Srmind uint32_t h = seed ^ len; 371.1Srmind 381.1Srmind while (len >= sizeof(uint32_t)) { 391.1Srmind uint32_t k; 401.1Srmind 411.1Srmind k = data[0]; 421.1Srmind k |= data[1] << 8; 431.1Srmind k |= data[2] << 16; 441.1Srmind k |= data[3] << 24; 451.1Srmind 461.1Srmind k *= m; 471.1Srmind k ^= k >> r; 481.1Srmind k *= m; 491.1Srmind 501.1Srmind h *= m; 511.1Srmind h ^= k; 521.1Srmind 531.1Srmind data += sizeof(uint32_t); 541.1Srmind len -= sizeof(uint32_t); 551.1Srmind } 561.1Srmind 571.1Srmind /* Handle the last few bytes of the input array. */ 581.1Srmind switch (len) { 591.1Srmind case 3: 601.1Srmind h ^= data[2] << 16; 611.1Srmind case 2: 621.1Srmind h ^= data[1] << 8; 631.1Srmind case 1: 641.1Srmind h ^= data[0]; 651.1Srmind h *= m; 661.1Srmind } 671.1Srmind 681.1Srmind /* 691.1Srmind * Do a few final mixes of the hash to ensure the last few 701.1Srmind * bytes are well-incorporated. 711.1Srmind */ 721.1Srmind h ^= h >> 13; 731.1Srmind h *= m; 741.1Srmind h ^= h >> 15; 751.1Srmind 761.1Srmind return h; 771.1Srmind} 78