xref: /linux/drivers/md/dm-vdo/murmurhash3.c (revision 7ec462100ef9142344ddbf86f2c3008b97acddbe)
1a3957b1fSMatthew Sakai // SPDX-License-Identifier: LGPL-2.1+
2a3957b1fSMatthew Sakai /*
3a3957b1fSMatthew Sakai  * MurmurHash3 was written by Austin Appleby, and is placed in the public
4a3957b1fSMatthew Sakai  * domain. The author hereby disclaims copyright to this source code.
5a3957b1fSMatthew Sakai  *
6a3957b1fSMatthew Sakai  * Adapted by John Wiele (jwiele@redhat.com).
7a3957b1fSMatthew Sakai  */
8a3957b1fSMatthew Sakai 
9a3957b1fSMatthew Sakai #include "murmurhash3.h"
10a3957b1fSMatthew Sakai 
11*5f60d5f6SAl Viro #include <linux/unaligned.h>
12d7e12014SKen Raeburn 
rotl64(u64 x,s8 r)13a3957b1fSMatthew Sakai static inline u64 rotl64(u64 x, s8 r)
14a3957b1fSMatthew Sakai {
15a3957b1fSMatthew Sakai 	return (x << r) | (x >> (64 - r));
16a3957b1fSMatthew Sakai }
17a3957b1fSMatthew Sakai 
18a3957b1fSMatthew Sakai #define ROTL64(x, y) rotl64(x, y)
19a3957b1fSMatthew Sakai 
20a3957b1fSMatthew Sakai /* Finalization mix - force all bits of a hash block to avalanche */
21a3957b1fSMatthew Sakai 
fmix64(u64 k)22a3957b1fSMatthew Sakai static __always_inline u64 fmix64(u64 k)
23a3957b1fSMatthew Sakai {
24a3957b1fSMatthew Sakai 	k ^= k >> 33;
25a3957b1fSMatthew Sakai 	k *= 0xff51afd7ed558ccdLLU;
26a3957b1fSMatthew Sakai 	k ^= k >> 33;
27a3957b1fSMatthew Sakai 	k *= 0xc4ceb9fe1a85ec53LLU;
28a3957b1fSMatthew Sakai 	k ^= k >> 33;
29a3957b1fSMatthew Sakai 
30a3957b1fSMatthew Sakai 	return k;
31a3957b1fSMatthew Sakai }
32a3957b1fSMatthew Sakai 
murmurhash3_128(const void * key,const int len,const u32 seed,void * out)33a3957b1fSMatthew Sakai void murmurhash3_128(const void *key, const int len, const u32 seed, void *out)
34a3957b1fSMatthew Sakai {
35a3957b1fSMatthew Sakai 	const u8 *data = key;
36a3957b1fSMatthew Sakai 	const int nblocks = len / 16;
37a3957b1fSMatthew Sakai 
38a3957b1fSMatthew Sakai 	u64 h1 = seed;
39a3957b1fSMatthew Sakai 	u64 h2 = seed;
40a3957b1fSMatthew Sakai 
41a3957b1fSMatthew Sakai 	const u64 c1 = 0x87c37b91114253d5LLU;
42a3957b1fSMatthew Sakai 	const u64 c2 = 0x4cf5ad432745937fLLU;
43a3957b1fSMatthew Sakai 
44d7e12014SKen Raeburn 	u64 *hash_out = out;
45d7e12014SKen Raeburn 
46a3957b1fSMatthew Sakai 	/* body */
47a3957b1fSMatthew Sakai 
48a3957b1fSMatthew Sakai 	const u64 *blocks = (const u64 *)(data);
49a3957b1fSMatthew Sakai 
50a3957b1fSMatthew Sakai 	int i;
51a3957b1fSMatthew Sakai 
52a3957b1fSMatthew Sakai 	for (i = 0; i < nblocks; i++) {
53d7e12014SKen Raeburn 		u64 k1 = get_unaligned_le64(&blocks[i * 2]);
54d7e12014SKen Raeburn 		u64 k2 = get_unaligned_le64(&blocks[i * 2 + 1]);
55a3957b1fSMatthew Sakai 
56a3957b1fSMatthew Sakai 		k1 *= c1;
57a3957b1fSMatthew Sakai 		k1 = ROTL64(k1, 31);
58a3957b1fSMatthew Sakai 		k1 *= c2;
59a3957b1fSMatthew Sakai 		h1 ^= k1;
60a3957b1fSMatthew Sakai 
61a3957b1fSMatthew Sakai 		h1 = ROTL64(h1, 27);
62a3957b1fSMatthew Sakai 		h1 += h2;
63a3957b1fSMatthew Sakai 		h1 = h1 * 5 + 0x52dce729;
64a3957b1fSMatthew Sakai 
65a3957b1fSMatthew Sakai 		k2 *= c2;
66a3957b1fSMatthew Sakai 		k2 = ROTL64(k2, 33);
67a3957b1fSMatthew Sakai 		k2 *= c1;
68a3957b1fSMatthew Sakai 		h2 ^= k2;
69a3957b1fSMatthew Sakai 
70a3957b1fSMatthew Sakai 		h2 = ROTL64(h2, 31);
71a3957b1fSMatthew Sakai 		h2 += h1;
72a3957b1fSMatthew Sakai 		h2 = h2 * 5 + 0x38495ab5;
73a3957b1fSMatthew Sakai 	}
74a3957b1fSMatthew Sakai 
75a3957b1fSMatthew Sakai 	/* tail */
76a3957b1fSMatthew Sakai 
77a3957b1fSMatthew Sakai 	{
78a3957b1fSMatthew Sakai 		const u8 *tail = (const u8 *)(data + nblocks * 16);
79a3957b1fSMatthew Sakai 
80a3957b1fSMatthew Sakai 		u64 k1 = 0;
81a3957b1fSMatthew Sakai 		u64 k2 = 0;
82a3957b1fSMatthew Sakai 
83a3957b1fSMatthew Sakai 		switch (len & 15) {
84a3957b1fSMatthew Sakai 		case 15:
85a3957b1fSMatthew Sakai 			k2 ^= ((u64)tail[14]) << 48;
86a3957b1fSMatthew Sakai 			fallthrough;
87a3957b1fSMatthew Sakai 		case 14:
88a3957b1fSMatthew Sakai 			k2 ^= ((u64)tail[13]) << 40;
89a3957b1fSMatthew Sakai 			fallthrough;
90a3957b1fSMatthew Sakai 		case 13:
91a3957b1fSMatthew Sakai 			k2 ^= ((u64)tail[12]) << 32;
92a3957b1fSMatthew Sakai 			fallthrough;
93a3957b1fSMatthew Sakai 		case 12:
94a3957b1fSMatthew Sakai 			k2 ^= ((u64)tail[11]) << 24;
95a3957b1fSMatthew Sakai 			fallthrough;
96a3957b1fSMatthew Sakai 		case 11:
97a3957b1fSMatthew Sakai 			k2 ^= ((u64)tail[10]) << 16;
98a3957b1fSMatthew Sakai 			fallthrough;
99a3957b1fSMatthew Sakai 		case 10:
100a3957b1fSMatthew Sakai 			k2 ^= ((u64)tail[9]) << 8;
101a3957b1fSMatthew Sakai 			fallthrough;
102a3957b1fSMatthew Sakai 		case 9:
103a3957b1fSMatthew Sakai 			k2 ^= ((u64)tail[8]) << 0;
104a3957b1fSMatthew Sakai 			k2 *= c2;
105a3957b1fSMatthew Sakai 			k2 = ROTL64(k2, 33);
106a3957b1fSMatthew Sakai 			k2 *= c1;
107a3957b1fSMatthew Sakai 			h2 ^= k2;
108a3957b1fSMatthew Sakai 			fallthrough;
109a3957b1fSMatthew Sakai 
110a3957b1fSMatthew Sakai 		case 8:
111a3957b1fSMatthew Sakai 			k1 ^= ((u64)tail[7]) << 56;
112a3957b1fSMatthew Sakai 			fallthrough;
113a3957b1fSMatthew Sakai 		case 7:
114a3957b1fSMatthew Sakai 			k1 ^= ((u64)tail[6]) << 48;
115a3957b1fSMatthew Sakai 			fallthrough;
116a3957b1fSMatthew Sakai 		case 6:
117a3957b1fSMatthew Sakai 			k1 ^= ((u64)tail[5]) << 40;
118a3957b1fSMatthew Sakai 			fallthrough;
119a3957b1fSMatthew Sakai 		case 5:
120a3957b1fSMatthew Sakai 			k1 ^= ((u64)tail[4]) << 32;
121a3957b1fSMatthew Sakai 			fallthrough;
122a3957b1fSMatthew Sakai 		case 4:
123a3957b1fSMatthew Sakai 			k1 ^= ((u64)tail[3]) << 24;
124a3957b1fSMatthew Sakai 			fallthrough;
125a3957b1fSMatthew Sakai 		case 3:
126a3957b1fSMatthew Sakai 			k1 ^= ((u64)tail[2]) << 16;
127a3957b1fSMatthew Sakai 			fallthrough;
128a3957b1fSMatthew Sakai 		case 2:
129a3957b1fSMatthew Sakai 			k1 ^= ((u64)tail[1]) << 8;
130a3957b1fSMatthew Sakai 			fallthrough;
131a3957b1fSMatthew Sakai 		case 1:
132a3957b1fSMatthew Sakai 			k1 ^= ((u64)tail[0]) << 0;
133a3957b1fSMatthew Sakai 			k1 *= c1;
134a3957b1fSMatthew Sakai 			k1 = ROTL64(k1, 31);
135a3957b1fSMatthew Sakai 			k1 *= c2;
136a3957b1fSMatthew Sakai 			h1 ^= k1;
137a3957b1fSMatthew Sakai 			break;
138a3957b1fSMatthew Sakai 		default:
139a3957b1fSMatthew Sakai 			break;
140f141dde5SMatthew Sakai 		}
141a3957b1fSMatthew Sakai 	}
142a3957b1fSMatthew Sakai 	/* finalization */
143a3957b1fSMatthew Sakai 
144a3957b1fSMatthew Sakai 	h1 ^= len;
145a3957b1fSMatthew Sakai 	h2 ^= len;
146a3957b1fSMatthew Sakai 
147a3957b1fSMatthew Sakai 	h1 += h2;
148a3957b1fSMatthew Sakai 	h2 += h1;
149a3957b1fSMatthew Sakai 
150a3957b1fSMatthew Sakai 	h1 = fmix64(h1);
151a3957b1fSMatthew Sakai 	h2 = fmix64(h2);
152a3957b1fSMatthew Sakai 
153a3957b1fSMatthew Sakai 	h1 += h2;
154a3957b1fSMatthew Sakai 	h2 += h1;
155a3957b1fSMatthew Sakai 
156d7e12014SKen Raeburn 	put_unaligned_le64(h1, &hash_out[0]);
157d7e12014SKen Raeburn 	put_unaligned_le64(h2, &hash_out[1]);
158a3957b1fSMatthew Sakai }
159