1eda14cbcSMatt Macy // Copyright (c) 2011 Google, Inc.
2eda14cbcSMatt Macy //
3eda14cbcSMatt Macy // Permission is hereby granted, free of charge, to any person obtaining a copy
4eda14cbcSMatt Macy // of this software and associated documentation files (the "Software"), to deal
5eda14cbcSMatt Macy // in the Software without restriction, including without limitation the rights
6eda14cbcSMatt Macy // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7eda14cbcSMatt Macy // copies of the Software, and to permit persons to whom the Software is
8eda14cbcSMatt Macy // furnished to do so, subject to the following conditions:
9eda14cbcSMatt Macy //
10eda14cbcSMatt Macy // The above copyright notice and this permission notice shall be included in
11eda14cbcSMatt Macy // all copies or substantial portions of the Software.
12eda14cbcSMatt Macy //
13eda14cbcSMatt Macy // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14eda14cbcSMatt Macy // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15eda14cbcSMatt Macy // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16eda14cbcSMatt Macy // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17eda14cbcSMatt Macy // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18eda14cbcSMatt Macy // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19eda14cbcSMatt Macy // THE SOFTWARE.
20eda14cbcSMatt Macy
21eda14cbcSMatt Macy /*
22eda14cbcSMatt Macy * Copyright (c) 2017 by Delphix. All rights reserved.
23eda14cbcSMatt Macy */
24eda14cbcSMatt Macy
25eda14cbcSMatt Macy #include <cityhash.h>
26eda14cbcSMatt Macy
27eda14cbcSMatt Macy #define HASH_K1 0xb492b66fbe98f273ULL
28eda14cbcSMatt Macy #define HASH_K2 0x9ae16a3b2f90404fULL
29eda14cbcSMatt Macy
30eda14cbcSMatt Macy /*
31eda14cbcSMatt Macy * Bitwise right rotate. Normally this will compile to a single
32eda14cbcSMatt Macy * instruction.
33eda14cbcSMatt Macy */
34eda14cbcSMatt Macy static inline uint64_t
rotate(uint64_t val,int shift)35eda14cbcSMatt Macy rotate(uint64_t val, int shift)
36eda14cbcSMatt Macy {
37eda14cbcSMatt Macy // Avoid shifting by 64: doing so yields an undefined result.
38eda14cbcSMatt Macy return (shift == 0 ? val : (val >> shift) | (val << (64 - shift)));
39eda14cbcSMatt Macy }
40eda14cbcSMatt Macy
41eda14cbcSMatt Macy static inline uint64_t
cityhash_helper(uint64_t u,uint64_t v,uint64_t mul)42eda14cbcSMatt Macy cityhash_helper(uint64_t u, uint64_t v, uint64_t mul)
43eda14cbcSMatt Macy {
44eda14cbcSMatt Macy uint64_t a = (u ^ v) * mul;
45eda14cbcSMatt Macy a ^= (a >> 47);
46eda14cbcSMatt Macy uint64_t b = (v ^ a) * mul;
47eda14cbcSMatt Macy b ^= (b >> 47);
48eda14cbcSMatt Macy b *= mul;
49eda14cbcSMatt Macy return (b);
50eda14cbcSMatt Macy }
51eda14cbcSMatt Macy
52*7a7741afSMartin Matuska static inline uint64_t
cityhash_impl(uint64_t w1,uint64_t w2,uint64_t w3,uint64_t w4)53*7a7741afSMartin Matuska cityhash_impl(uint64_t w1, uint64_t w2, uint64_t w3, uint64_t w4)
54eda14cbcSMatt Macy {
55eda14cbcSMatt Macy uint64_t mul = HASH_K2 + 64;
56eda14cbcSMatt Macy uint64_t a = w1 * HASH_K1;
57eda14cbcSMatt Macy uint64_t b = w2;
58eda14cbcSMatt Macy uint64_t c = w4 * mul;
59eda14cbcSMatt Macy uint64_t d = w3 * HASH_K2;
60eda14cbcSMatt Macy return (cityhash_helper(rotate(a + b, 43) + rotate(c, 30) + d,
61eda14cbcSMatt Macy a + rotate(b + HASH_K2, 18) + c, mul));
62*7a7741afSMartin Matuska }
63eda14cbcSMatt Macy
64*7a7741afSMartin Matuska /*
65*7a7741afSMartin Matuska * Passing w as the 2nd argument could save one 64-bit multiplication.
66*7a7741afSMartin Matuska */
67*7a7741afSMartin Matuska uint64_t
cityhash1(uint64_t w)68*7a7741afSMartin Matuska cityhash1(uint64_t w)
69*7a7741afSMartin Matuska {
70*7a7741afSMartin Matuska return (cityhash_impl(0, w, 0, 0));
71*7a7741afSMartin Matuska }
72*7a7741afSMartin Matuska
73*7a7741afSMartin Matuska uint64_t
cityhash2(uint64_t w1,uint64_t w2)74*7a7741afSMartin Matuska cityhash2(uint64_t w1, uint64_t w2)
75*7a7741afSMartin Matuska {
76*7a7741afSMartin Matuska return (cityhash_impl(w1, w2, 0, 0));
77*7a7741afSMartin Matuska }
78*7a7741afSMartin Matuska
79*7a7741afSMartin Matuska uint64_t
cityhash3(uint64_t w1,uint64_t w2,uint64_t w3)80*7a7741afSMartin Matuska cityhash3(uint64_t w1, uint64_t w2, uint64_t w3)
81*7a7741afSMartin Matuska {
82*7a7741afSMartin Matuska return (cityhash_impl(w1, w2, w3, 0));
83*7a7741afSMartin Matuska }
84*7a7741afSMartin Matuska
85*7a7741afSMartin Matuska uint64_t
cityhash4(uint64_t w1,uint64_t w2,uint64_t w3,uint64_t w4)86*7a7741afSMartin Matuska cityhash4(uint64_t w1, uint64_t w2, uint64_t w3, uint64_t w4)
87*7a7741afSMartin Matuska {
88*7a7741afSMartin Matuska return (cityhash_impl(w1, w2, w3, w4));
89eda14cbcSMatt Macy }
90eda14cbcSMatt Macy
91eda14cbcSMatt Macy #if defined(_KERNEL)
92*7a7741afSMartin Matuska EXPORT_SYMBOL(cityhash1);
93*7a7741afSMartin Matuska EXPORT_SYMBOL(cityhash2);
94*7a7741afSMartin Matuska EXPORT_SYMBOL(cityhash3);
95eda14cbcSMatt Macy EXPORT_SYMBOL(cityhash4);
96eda14cbcSMatt Macy #endif
97