Path: blob/main/sys/contrib/openzfs/module/zcommon/cityhash.c
48383 views
// SPDX-License-Identifier: MIT1//2// Copyright (c) 2011 Google, Inc.3//4// Permission is hereby granted, free of charge, to any person obtaining a copy5// of this software and associated documentation files (the "Software"), to deal6// in the Software without restriction, including without limitation the rights7// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell8// copies of the Software, and to permit persons to whom the Software is9// furnished to do so, subject to the following conditions:10//11// The above copyright notice and this permission notice shall be included in12// all copies or substantial portions of the Software.13//14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE17// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN20// THE SOFTWARE.2122/*23* Copyright (c) 2017 by Delphix. All rights reserved.24*/2526#include <cityhash.h>2728#define HASH_K1 0xb492b66fbe98f273ULL29#define HASH_K2 0x9ae16a3b2f90404fULL3031/*32* Bitwise right rotate. Normally this will compile to a single33* instruction.34*/35static inline uint64_t36rotate(uint64_t val, int shift)37{38// Avoid shifting by 64: doing so yields an undefined result.39return (shift == 0 ? val : (val >> shift) | (val << (64 - shift)));40}4142static inline uint64_t43cityhash_helper(uint64_t u, uint64_t v, uint64_t mul)44{45uint64_t a = (u ^ v) * mul;46a ^= (a >> 47);47uint64_t b = (v ^ a) * mul;48b ^= (b >> 47);49b *= mul;50return (b);51}5253static inline uint64_t54cityhash_impl(uint64_t w1, uint64_t w2, uint64_t w3, uint64_t w4)55{56uint64_t mul = HASH_K2 + 64;57uint64_t a = w1 * HASH_K1;58uint64_t b = w2;59uint64_t c = w4 * mul;60uint64_t d = w3 * HASH_K2;61return (cityhash_helper(rotate(a + b, 43) + rotate(c, 30) + d,62a + rotate(b + HASH_K2, 18) + c, mul));63}6465/*66* Passing w as the 2nd argument could save one 64-bit multiplication.67*/68uint64_t69cityhash1(uint64_t w)70{71return (cityhash_impl(0, w, 0, 0));72}7374uint64_t75cityhash2(uint64_t w1, uint64_t w2)76{77return (cityhash_impl(w1, w2, 0, 0));78}7980uint64_t81cityhash3(uint64_t w1, uint64_t w2, uint64_t w3)82{83return (cityhash_impl(w1, w2, w3, 0));84}8586uint64_t87cityhash4(uint64_t w1, uint64_t w2, uint64_t w3, uint64_t w4)88{89return (cityhash_impl(w1, w2, w3, w4));90}9192#if defined(_KERNEL)93EXPORT_SYMBOL(cityhash1);94EXPORT_SYMBOL(cityhash2);95EXPORT_SYMBOL(cityhash3);96EXPORT_SYMBOL(cityhash4);97#endif9899100