1*1d2baefcSGeorge V. Neville-Neil /*- 2*1d2baefcSGeorge V. Neville-Neil * Copyright (c) 2014 Dag-Erling Smørgrav 3*1d2baefcSGeorge V. Neville-Neil * All rights reserved. 4*1d2baefcSGeorge V. Neville-Neil * 5*1d2baefcSGeorge V. Neville-Neil * Redistribution and use in source and binary forms, with or without 6*1d2baefcSGeorge V. Neville-Neil * modification, are permitted provided that the following conditions 7*1d2baefcSGeorge V. Neville-Neil * are met: 8*1d2baefcSGeorge V. Neville-Neil * 1. Redistributions of source code must retain the above copyright 9*1d2baefcSGeorge V. Neville-Neil * notice, this list of conditions and the following disclaimer. 10*1d2baefcSGeorge V. Neville-Neil * 2. Redistributions in binary form must reproduce the above copyright 11*1d2baefcSGeorge V. Neville-Neil * notice, this list of conditions and the following disclaimer in the 12*1d2baefcSGeorge V. Neville-Neil * documentation and/or other materials provided with the distribution. 13*1d2baefcSGeorge V. Neville-Neil * 14*1d2baefcSGeorge V. Neville-Neil * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*1d2baefcSGeorge V. Neville-Neil * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*1d2baefcSGeorge V. Neville-Neil * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*1d2baefcSGeorge V. Neville-Neil * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*1d2baefcSGeorge V. Neville-Neil * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*1d2baefcSGeorge V. Neville-Neil * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*1d2baefcSGeorge V. Neville-Neil * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*1d2baefcSGeorge V. Neville-Neil * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*1d2baefcSGeorge V. Neville-Neil * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*1d2baefcSGeorge V. Neville-Neil * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*1d2baefcSGeorge V. Neville-Neil * SUCH DAMAGE. 25*1d2baefcSGeorge V. Neville-Neil */ 26*1d2baefcSGeorge V. Neville-Neil 27*1d2baefcSGeorge V. Neville-Neil #include <sys/hash.h> 28*1d2baefcSGeorge V. Neville-Neil #include <sys/endian.h> 29*1d2baefcSGeorge V. Neville-Neil #include <sys/stdint.h> 30*1d2baefcSGeorge V. Neville-Neil #include <sys/types.h> 31*1d2baefcSGeorge V. Neville-Neil 32*1d2baefcSGeorge V. Neville-Neil #define rol32(i32, n) ((i32) << (n) | (i32) >> (32 - (n))) 33*1d2baefcSGeorge V. Neville-Neil 34*1d2baefcSGeorge V. Neville-Neil /* 35*1d2baefcSGeorge V. Neville-Neil * $FreeBSD$ 36*1d2baefcSGeorge V. Neville-Neil * Simple implementation of the Murmur3-32 hash function optimized for 37*1d2baefcSGeorge V. Neville-Neil * aligned sequences of 32-bit words. If len is not a multiple of 4, it 38*1d2baefcSGeorge V. Neville-Neil * will be rounded down, droping trailer bytes. 39*1d2baefcSGeorge V. Neville-Neil */ 40*1d2baefcSGeorge V. Neville-Neil uint32_t 41*1d2baefcSGeorge V. Neville-Neil murmur3_aligned_32(const void *data, size_t len, uint32_t seed) 42*1d2baefcSGeorge V. Neville-Neil { 43*1d2baefcSGeorge V. Neville-Neil const uint32_t *data32; 44*1d2baefcSGeorge V. Neville-Neil uint32_t hash, k; 45*1d2baefcSGeorge V. Neville-Neil size_t res; 46*1d2baefcSGeorge V. Neville-Neil 47*1d2baefcSGeorge V. Neville-Neil /* initialize */ 48*1d2baefcSGeorge V. Neville-Neil len -= len % sizeof(*data32); 49*1d2baefcSGeorge V. Neville-Neil res = len; 50*1d2baefcSGeorge V. Neville-Neil data32 = data; 51*1d2baefcSGeorge V. Neville-Neil hash = seed; 52*1d2baefcSGeorge V. Neville-Neil 53*1d2baefcSGeorge V. Neville-Neil /* iterate */ 54*1d2baefcSGeorge V. Neville-Neil for (res = 0; res < len; res += sizeof(*data32), data32++) { 55*1d2baefcSGeorge V. Neville-Neil k = le32toh(*data32); 56*1d2baefcSGeorge V. Neville-Neil k *= 0xcc9e2d51; 57*1d2baefcSGeorge V. Neville-Neil k = rol32(k, 15); 58*1d2baefcSGeorge V. Neville-Neil k *= 0x1b873593; 59*1d2baefcSGeorge V. Neville-Neil hash ^= k; 60*1d2baefcSGeorge V. Neville-Neil hash = rol32(hash, 13); 61*1d2baefcSGeorge V. Neville-Neil hash *= 5; 62*1d2baefcSGeorge V. Neville-Neil hash += 0xe6546b64; 63*1d2baefcSGeorge V. Neville-Neil } 64*1d2baefcSGeorge V. Neville-Neil 65*1d2baefcSGeorge V. Neville-Neil /* finalize */ 66*1d2baefcSGeorge V. Neville-Neil hash ^= (uint32_t)len; 67*1d2baefcSGeorge V. Neville-Neil hash ^= hash >> 16; 68*1d2baefcSGeorge V. Neville-Neil hash *= 0x85ebca6b; 69*1d2baefcSGeorge V. Neville-Neil hash ^= hash >> 13; 70*1d2baefcSGeorge V. Neville-Neil hash *= 0xc2b2ae35; 71*1d2baefcSGeorge V. Neville-Neil hash ^= hash >> 16; 72*1d2baefcSGeorge V. Neville-Neil return (hash); 73*1d2baefcSGeorge V. Neville-Neil } 74*1d2baefcSGeorge V. Neville-Neil 75