From 5aad40ce9d6733199e7a6bf0ea2a862f7d47d334 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Fri, 25 Sep 2020 03:38:29 -0500 Subject: [PATCH] move xxHash to submodule --- .gitmodules | 4 + import/xxHash | 1 + projects/cxbx/CMakeLists.txt | 1 + projects/cxbxr-emu/CMakeLists.txt | 1 + src/common/util/xxh3.h | 1222 ----------------------------- src/common/util/xxhash.c | 1024 ------------------------ src/common/util/xxhash.h | 512 ------------ src/core/kernel/init/CxbxKrnl.cpp | 2 +- 8 files changed, 8 insertions(+), 2759 deletions(-) create mode 160000 import/xxHash delete mode 100644 src/common/util/xxh3.h delete mode 100644 src/common/util/xxhash.c delete mode 100644 src/common/util/xxhash.h diff --git a/.gitmodules b/.gitmodules index bfa6e6884..538bffa11 100644 --- a/.gitmodules +++ b/.gitmodules @@ -21,3 +21,7 @@ [submodule "import/SDL2"] path = import/SDL2 url = https://github.com/SDL-mirror/SDL +[submodule "import/xxHash"] + path = import/xxHash + url = https://github.com/Cyan4973/xxHash.git + branch = release diff --git a/import/xxHash b/import/xxHash new file mode 160000 index 000000000..94e5f23e7 --- /dev/null +++ b/import/xxHash @@ -0,0 +1 @@ +Subproject commit 94e5f23e736f2bb67ebdf90727353e65344f9fc0 diff --git a/projects/cxbx/CMakeLists.txt b/projects/cxbx/CMakeLists.txt index 201b23668..819cb93e7 100644 --- a/projects/cxbx/CMakeLists.txt +++ b/projects/cxbx/CMakeLists.txt @@ -22,6 +22,7 @@ include_directories( "${CXBXR_ROOT_DIR}/import/libtomcrypt/src/headers" "${CXBXR_ROOT_DIR}/import/winpcap/Include" "${CXBXR_ROOT_DIR}/import/SDL2/include" + "${CXBXR_ROOT_DIR}/import/xxHash" ) link_directories( diff --git a/projects/cxbxr-emu/CMakeLists.txt b/projects/cxbxr-emu/CMakeLists.txt index 890d2adf2..7f2467c43 100644 --- a/projects/cxbxr-emu/CMakeLists.txt +++ b/projects/cxbxr-emu/CMakeLists.txt @@ -24,6 +24,7 @@ include_directories( "${CXBXR_ROOT_DIR}/import/libtommath" "${CXBXR_ROOT_DIR}/import/libtomcrypt/src/headers" "${CXBXR_ROOT_DIR}/import/winpcap/Include" + "${CXBXR_ROOT_DIR}/import/xxHash" ) link_directories( diff --git a/src/common/util/xxh3.h b/src/common/util/xxh3.h deleted file mode 100644 index 9d4ad5999..000000000 --- a/src/common/util/xxh3.h +++ /dev/null @@ -1,1222 +0,0 @@ -/* - xxHash - Extremely Fast Hash algorithm - Development source file for `xxh3` - Copyright (C) 2019-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - You can contact the author at : - - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - -/* Note : - This file is separated for development purposes. - It will be integrated into `xxhash.c` when development phase is complete. -*/ - -#ifndef XXH3_H -#define XXH3_H - - -/* === Dependencies === */ - -#undef XXH_INLINE_ALL /* in case it's already defined */ -#define XXH_INLINE_ALL -#include "xxhash.h" - -#undef NDEBUG /* avoid redefinition */ -#define NDEBUG /* disable assert (release mode) */ -#include -#ifndef NDEBUG -# define NDEBUG -# define UNDEF_NDEBUG -# include -#endif - - -/* === Compiler specifics === */ - -#if !(defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) /* < C99 */ -# define restrict /* disable */ -#endif - -#if defined(__GNUC__) -# if defined(__AVX2__) -# include -# elif defined(__SSE2__) -# include -# elif defined(__ARM_NEON__) || defined(__ARM_NEON) -# define inline __inline__ /* clang bug */ -# include -# undef inline -# endif -#elif defined(_MSC_VER) -# include -#endif - - - -/* ========================================== - * Vectorization detection - * ========================================== */ -#define XXH_SCALAR 0 -#define XXH_SSE2 1 -#define XXH_AVX2 2 -#define XXH_NEON 3 -#define XXH_VSX 4 - -#ifndef XXH_VECTOR /* can be defined on command line */ -# if defined(__AVX2__) -# define XXH_VECTOR XXH_AVX2 -# elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) -# define XXH_VECTOR XXH_SSE2 -# elif defined(__GNUC__) /* msvc support maybe later */ \ - && (defined(__ARM_NEON__) || defined(__ARM_NEON)) \ - && defined(__LITTLE_ENDIAN__) /* ARM big endian is a thing */ -# define XXH_VECTOR XXH_NEON -# elif defined(__PPC64__) && defined(__VSX__) && defined(__GNUC__) -# define XXH_VECTOR XXH_VSX -# else -# define XXH_VECTOR XXH_SCALAR -# endif -#endif - -/* control alignment of accumulator, - * for compatibility with fast vector loads */ -#ifndef XXH_ACC_ALIGN -# if XXH_VECTOR == 0 /* scalar */ -# define XXH_ACC_ALIGN 8 -# elif XXH_VECTOR == 1 /* sse2 */ -# define XXH_ACC_ALIGN 16 -# elif XXH_VECTOR == 2 /* avx2 */ -# define XXH_ACC_ALIGN 32 -# elif XXH_VECTOR == 3 /* neon */ -# define XXH_ACC_ALIGN 16 -# elif XXH_VECTOR == 4 /* vsx */ -# define XXH_ACC_ALIGN 16 -# endif -#endif - -/* U64 XXH_mult32to64(U32 a, U64 b) { return (U64)a * (U64)b; } */ -#ifdef _MSC_VER -# include - /* MSVC doesn't do a good job with the mull detection. */ -# define XXH_mult32to64 __emulu -#else -# define XXH_mult32to64(x, y) ((U64)((x) & 0xFFFFFFFF) * (U64)((y) & 0xFFFFFFFF)) -#endif - -/* VSX stuff */ -#if XXH_VECTOR == XXH_VSX -# include -# undef vector -typedef __vector unsigned long long U64x2; -typedef __vector unsigned U32x4; -/* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */ -XXH_FORCE_INLINE U64x2 XXH_vsxMultOdd(U32x4 a, U32x4 b) { - U64x2 result; - __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); - return result; -} -XXH_FORCE_INLINE U64x2 XXH_vsxMultEven(U32x4 a, U32x4 b) { - U64x2 result; - __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); - return result; -} -#endif - - -/* ========================================== - * XXH3 default settings - * ========================================== */ - -#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH_SECRET_SIZE_MIN */ - -#if (XXH_SECRET_DEFAULT_SIZE < XXH_SECRET_SIZE_MIN) -# error "default keyset is not large enough" -#endif - -XXH_ALIGN(64) static const BYTE kSecret[XXH_SECRET_DEFAULT_SIZE] = { - 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, - 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, - 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, - 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c, - 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, - 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, - 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d, - 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, - - 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, - 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e, - 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, - 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, -}; - - -#if defined(__GNUC__) && defined(__i386__) -/* GCC is stupid and tries to vectorize this. - * This tells GCC that it is wrong. */ -__attribute__((__target__("no-sse"))) -#endif -static U64 -XXH3_mul128_fold64(U64 ll1, U64 ll2) -{ -#if defined(__SIZEOF_INT128__) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128) - - __uint128_t lll = (__uint128_t)ll1 * ll2; - return (U64)lll ^ (U64)(lll >> 64); - -#elif defined(_M_X64) || defined(_M_IA64) - -#ifndef _MSC_VER -# pragma intrinsic(_umul128) -#endif - U64 llhigh; - U64 const lllow = _umul128(ll1, ll2, &llhigh); - return lllow ^ llhigh; - - /* We have to do it out manually on 32-bit. - * This is a modified, unrolled, widened, and optimized version of the - * mulqdu routine from Hacker's Delight. - * - * https://www.hackersdelight.org/hdcodetxt/mulqdu.c.txt - * - * This was modified to use U32->U64 multiplication instead - * of U16->U32, to add the high and low values in the end, - * be endian-independent, and I added a partial assembly - * implementation for ARM. */ - - /* An easy 128-bit folding multiply on ARMv6T2 and ARMv7-A/R can be done with - * the mighty umaal (Unsigned Multiply Accumulate Accumulate Long) which takes 4 cycles - * or less, doing a long multiply and adding two 32-bit integers: - * - * void umaal(U32 *RdLo, U32 *RdHi, U32 Rn, U32 Rm) - * { - * U64 prodAcc = (U64)Rn * (U64)Rm; - * prodAcc += *RdLo; - * prodAcc += *RdHi; - * *RdLo = prodAcc & 0xFFFFFFFF; - * *RdHi = prodAcc >> 32; - * } - * - * This is compared to umlal which adds to a single 64-bit integer: - * - * void umlal(U32 *RdLo, U32 *RdHi, U32 Rn, U32 Rm) - * { - * U64 prodAcc = (U64)Rn * (U64)Rm; - * prodAcc += (*RdLo | ((U64)*RdHi << 32); - * *RdLo = prodAcc & 0xFFFFFFFF; - * *RdHi = prodAcc >> 32; - * } - * - * Getting the compiler to emit them is like pulling teeth, and checking - * for it is annoying because ARMv7-M lacks this instruction. However, it - * is worth it, because this is an otherwise expensive operation. */ - - /* GCC-compatible, ARMv6t2 or ARMv7+, non-M variant, and 32-bit */ -#elif defined(__GNUC__) /* GCC-compatible */ \ - && defined(__ARM_ARCH) && !defined(__aarch64__) && !defined(__arm64__) /* 32-bit ARM */\ - && !defined(__ARM_ARCH_7M__) /* <- Not ARMv7-M vv*/ \ - && !(defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 0 && __TARGET_ARCH_THUMB == 4) \ - && (defined(__ARM_ARCH_6T2__) || __ARM_ARCH > 6) /* ARMv6T2 or later */ - - U32 w[4] = { 0 }; - U32 u[2] = { (U32)(ll1 >> 32), (U32)ll1 }; - U32 v[2] = { (U32)(ll2 >> 32), (U32)ll2 }; - U32 k; - - /* U64 t = (U64)u[1] * (U64)v[1]; - * w[3] = t & 0xFFFFFFFF; - * k = t >> 32; */ - __asm__("umull %0, %1, %2, %3" - : "=r" (w[3]), "=r" (k) - : "r" (u[1]), "r" (v[1])); - - /* t = (U64)u[0] * (U64)v[1] + w[2] + k; - * w[2] = t & 0xFFFFFFFF; - * k = t >> 32; */ - __asm__("umaal %0, %1, %2, %3" - : "+r" (w[2]), "+r" (k) - : "r" (u[0]), "r" (v[1])); - w[1] = k; - k = 0; - - /* t = (U64)u[1] * (U64)v[0] + w[2] + k; - * w[2] = t & 0xFFFFFFFF; - * k = t >> 32; */ - __asm__("umaal %0, %1, %2, %3" - : "+r" (w[2]), "+r" (k) - : "r" (u[1]), "r" (v[0])); - - /* t = (U64)u[0] * (U64)v[0] + w[1] + k; - * w[1] = t & 0xFFFFFFFF; - * k = t >> 32; */ - __asm__("umaal %0, %1, %2, %3" - : "+r" (w[1]), "+r" (k) - : "r" (u[0]), "r" (v[0])); - w[0] = k; - - return (w[1] | ((U64)w[0] << 32)) ^ (w[3] | ((U64)w[2] << 32)); - -#else /* Portable scalar version */ - - /* emulate 64x64->128b multiplication, using four 32x32->64 */ - U32 const h1 = (U32)(ll1 >> 32); - U32 const h2 = (U32)(ll2 >> 32); - U32 const l1 = (U32)ll1; - U32 const l2 = (U32)ll2; - - U64 const llh = XXH_mult32to64(h1, h2); - U64 const llm1 = XXH_mult32to64(l1, h2); - U64 const llm2 = XXH_mult32to64(h1, l2); - U64 const lll = XXH_mult32to64(l1, l2); - - U64 const t = lll + (llm1 << 32); - U64 const carry1 = t < lll; - - U64 const lllow = t + (llm2 << 32); - U64 const carry2 = lllow < t; - U64 const llhigh = llh + (llm1 >> 32) + (llm2 >> 32) + carry1 + carry2; - - return llhigh ^ lllow; - -#endif -} - - -static XXH64_hash_t XXH3_avalanche(U64 h64) -{ - h64 ^= h64 >> 37; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - return h64; -} - - -/* ========================================== - * Short keys - * ========================================== */ - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_1to3_64b(const void* data, size_t len, const void* keyPtr, XXH64_hash_t seed) -{ - assert(data != NULL); - assert(len > 1 && len <= 3); - assert(keyPtr != NULL); - { BYTE const c1 = ((const BYTE*)data)[0]; - BYTE const c2 = ((const BYTE*)data)[len >> 1]; - BYTE const c3 = ((const BYTE*)data)[len - 1]; - U32 const combined = ((U32)c1) + (((U32)c2) << 8) + (((U32)c3) << 16) + (((U32)len) << 24); - U64 const keyed = (U64)combined ^ (XXH_readLE64(keyPtr) + seed); - U64 const mixed = keyed * PRIME64_1; - return XXH3_avalanche(mixed); - } -} - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_4to8_64b(const void* data, size_t len, const void* keyPtr, XXH64_hash_t seed) -{ - assert(data != NULL); - assert(key != NULL); - assert(len >= 4 && len <= 8); - { U32 const in1 = XXH_readLE32(data); - U32 const in2 = XXH_readLE32((const BYTE*)data + len - 4); - U64 const in64 = in1 + ((U64)in2 << 32); - U64 const keyed = in64 ^ (XXH_readLE64(keyPtr) + seed); - U64 const mix64 = len + XXH3_mul128_fold64(keyed, PRIME64_1); - return XXH3_avalanche(mix64); - } -} - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_9to16_64b(const void* data, size_t len, const void* keyPtr, XXH64_hash_t seed) -{ - assert(data != NULL); - assert(key != NULL); - assert(len >= 9 && len <= 16); - { const U64* const key64 = (const U64*) keyPtr; - U64 const ll1 = XXH_readLE64(data) ^ (XXH_readLE64(key64) + seed); - U64 const ll2 = XXH_readLE64((const BYTE*)data + len - 8) ^ (XXH_readLE64(key64+1) - seed); - U64 const acc = len + (ll1 + ll2) + XXH3_mul128_fold64(ll1, ll2); - return XXH3_avalanche(acc); - } -} - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_0to16_64b(const void* data, size_t len, const void* keyPtr, XXH64_hash_t seed) -{ - assert(data != NULL); - assert(len <= 16); - { if (len > 8) return XXH3_len_9to16_64b(data, len, keyPtr, seed); - if (len >= 4) return XXH3_len_4to8_64b(data, len, keyPtr, seed); - if (len) return XXH3_len_1to3_64b(data, len, keyPtr, seed); - return 0; - } -} - - -/* === Long Keys === */ - -#define STRIPE_LEN 64 -#define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */ -#define ACC_NB (STRIPE_LEN / sizeof(U64)) - -XXH_FORCE_INLINE void -XXH3_accumulate_512(void* restrict acc, const void* restrict data, const void* restrict key) -{ -#if (XXH_VECTOR == XXH_AVX2) - - assert(((size_t)acc) & 31 == 0); - { XXH_ALIGN(32) __m256i* const xacc = (__m256i *) acc; - const __m256i* const xdata = (const __m256i *) data; /* not really aligned, just for ptr arithmetic, and because _mm256_loadu_si256() requires this type */ - const __m256i* const xkey = (const __m256i *) key; /* not really aligned, just for ptr arithmetic, and because _mm256_loadu_si256() requires this type */ - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(__m256i); i++) { - __m256i const d = _mm256_loadu_si256 (xdata+i); - __m256i const k = _mm256_loadu_si256 (xkey+i); - __m256i const dk = _mm256_xor_si256 (d,k); /* uint32 dk[8] = {d0+k0, d1+k1, d2+k2, d3+k3, ...} */ - __m256i const mul = _mm256_mul_epu32 (dk, _mm256_shuffle_epi32 (dk, 0x31)); /* uint64 mul[4] = {dk0*dk1, dk2*dk3, ...} */ - __m256i const add = _mm256_add_epi64(d, xacc[i]); - xacc[i] = _mm256_add_epi64(mul, add); - } } - -#elif (XXH_VECTOR == XXH_SSE2) - - assert(((size_t)acc) & 15 == 0); - { XXH_ALIGN(16) __m128i* const xacc = (__m128i *) acc; /* presumed */ - const __m128i* const xdata = (const __m128i *) data; /* not really aligned, just for ptr arithmetic, and because _mm_loadu_si128() requires this type */ - const __m128i* const xkey = (const __m128i *) key; /* not really aligned, just for ptr arithmetic, and because _mm_loadu_si128() requires this type */ - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(__m128i); i++) { - __m128i const d = _mm_loadu_si128 (xdata+i); - __m128i const k = _mm_loadu_si128 (xkey+i); - __m128i const dk = _mm_xor_si128 (d,k); /* uint32 dk[4] = {d0+k0, d1+k1, d2+k2, d3+k3} */ - __m128i const mul = _mm_mul_epu32 (dk, _mm_shuffle_epi32 (dk, 0x31)); /* uint64 mul[2] = {dk0*dk1,dk2*dk3} */ - __m128i const add = _mm_add_epi64(d, xacc[i]); - xacc[i] = _mm_add_epi64(mul, add); - } } - -#elif (XXH_VECTOR == XXH_NEON) - - assert((((size_t)acc) & 15) == 0); - { - XXH_ALIGN(16) uint64x2_t* const xacc = (uint64x2_t *) acc; - /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */ - uint32_t const* const xdata = (const uint32_t *) data; - uint32_t const* const xkey = (const uint32_t *) key; - - size_t i; - for (i=0; i < STRIPE_LEN / sizeof(uint64x2_t); i++) { -#if !defined(__aarch64__) && !defined(__arm64__) && defined(__GNUC__) /* ARM32-specific hack */ - /* vzip on ARMv7 Clang generates a lot of vmovs (technically vorrs) without this. - * vzip on 32-bit ARM NEON will overwrite the original register, and I think that Clang - * assumes I don't want to destroy it and tries to make a copy. This slows down the code - * a lot. - * aarch64 not only uses an entirely different syntax, but it requires three - * instructions... - * ext v1.16B, v0.16B, #8 // select high bits because aarch64 can't address them directly - * zip1 v3.2s, v0.2s, v1.2s // first zip - * zip2 v2.2s, v0.2s, v1.2s // second zip - * ...to do what ARM does in one: - * vzip.32 d0, d1 // Interleave high and low bits and overwrite. */ - - /* data_vec = xdata[i]; */ - uint32x4_t const data_vec = vld1q_u32(xdata + (i * 4)); - /* key_vec = xkey[i]; */ - uint32x4_t const key_vec = vld1q_u32(xkey + (i * 4)); - /* data_key = data_vec ^ key_vec; */ - uint32x4_t data_key; - /* Add first to prevent register swaps */ - /* xacc[i] += data_vec; */ - xacc[i] = vaddq_u64(xacc[i], vreinterpretq_u64_u32(data_vec)); - - data_key = veorq_u32(data_vec, key_vec); - - /* Here's the magic. We use the quirkiness of vzip to shuffle data_key in place. - * shuffle: data_key[0, 1, 2, 3] = data_key[0, 2, 1, 3] */ - __asm__("vzip.32 %e0, %f0" : "+w" (data_key)); - /* xacc[i] += (uint64x2_t) data_key[0, 1] * (uint64x2_t) data_key[2, 3]; */ - xacc[i] = vmlal_u32(xacc[i], vget_low_u32(data_key), vget_high_u32(data_key)); -#else - /* On aarch64, vshrn/vmovn seems to be equivalent to, if not faster than, the vzip method. */ - - /* data_vec = xdata[i]; */ - uint32x4_t const data_vec = vld1q_u32(xdata + (i * 4)); - /* key_vec = xkey[i]; */ - uint32x4_t const key_vec = vld1q_u32(xkey + (i * 4)); - /* data_key = data_vec ^ key_vec; */ - uint32x4_t const data_key = veorq_u32(data_vec, key_vec); - /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF); */ - uint32x2_t const data_key_lo = vmovn_u64 (vreinterpretq_u64_u32(data_key)); - /* data_key_hi = (uint32x2_t) (data_key >> 32); */ - uint32x2_t const data_key_hi = vshrn_n_u64 (vreinterpretq_u64_u32(data_key), 32); - /* xacc[i] += data_vec; */ - xacc[i] = vaddq_u64 (xacc[i], vreinterpretq_u64_u32(data_vec)); - /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */ - xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi); -#endif - } - } - -#elif XXH_VECTOR == XXH_VSX - U64x2* const xacc = (U64x2*) acc; /* presumed aligned */ - U64x2 const* const xdata = (U64x2 const*) data; /* no alignment restriction */ - U64x2 const* const xkey = (U64x2 const*) key; /* no alignment restriction */ - U64x2 const v32 = { 32, 32 }; - - size_t i; - for (i = 0; i < STRIPE_LEN / sizeof(U64x2); i++) { - /* data_vec = xdata[i]; */ - /* key_vec = xkey[i]; */ -#ifdef __BIG_ENDIAN__ - /* byteswap */ - U64x2 const data_vec = vec_revb(vec_vsx_ld(0, xdata + i)); - /* swap 32-bit words */ - U64x2 const key_vec = vec_rl(vec_vsx_ld(0, xkey + i), v32); -#else - U64x2 const data_vec = vec_vsx_ld(0, xdata + i); - U64x2 const key_vec = vec_vsx_ld(0, xkey + i); -#endif - U64x2 data_key = data_vec ^ key_vec; - /* shuffled = (data_key << 32) | (data_key >> 32); */ - U32x4 shuffled = (U32x4)vec_rl(data_key, v32); - /* product = ((U64x2)data_key & 0xFFFFFFFF) * ((U64x2)shuffled & 0xFFFFFFFF); */ - U64x2 product = XXH_vsxMultOdd((U32x4)data_key, shuffled); - - xacc[i] += product; - xacc[i] += data_vec; - } - -#else /* scalar variant of Accumulator - universal */ - - XXH_ALIGN(32) U64* const xacc = (U64*) acc; /* presumed aligned on 32-bytes boundaries, little hint for the auto-vectorizer */ - const char* const xdata = (const char*) data; /* no alignment restriction */ - const char* const xkey = (const char*) key; /* no alignment restriction */ - size_t i; - assert(((size_t)acc & 31) == 0); - for (i=0; i < ACC_NB; i++) { - U64 const data_val = XXH_readLE64(xdata + 8*i); - U64 const key_val = XXH_readLE64(xkey + 8*i); - U64 const data_key = key_val ^ data_val; - xacc[i] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32); - xacc[i] += data_val; - } - -#endif -} - -XXH_FORCE_INLINE void -XXH3_scrambleAcc(void* restrict acc, const void* restrict key) -{ -#if (XXH_VECTOR == XXH_AVX2) - - assert(((size_t)acc) & 31 == 0); - { XXH_ALIGN(32) __m256i* const xacc = (__m256i*) acc; - const __m256i* const xkey = (const __m256i *) key; /* not really aligned, just for ptr arithmetic, and because _mm256_loadu_si256() requires this argument type */ - const __m256i k1 = _mm256_set1_epi32((int)PRIME32_1); - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(__m256i); i++) { - __m256i data = xacc[i]; - __m256i const shifted = _mm256_srli_epi64(data, 47); - data = _mm256_xor_si256(data, shifted); - - { __m256i const k = _mm256_loadu_si256 (xkey+i); - __m256i const dk = _mm256_xor_si256 (data, k); /* U32 dk[4] = {d0+k0, d1+k1, d2+k2, d3+k3} */ - - __m256i const dk1 = _mm256_mul_epu32 (dk, k1); - - __m256i const d2 = _mm256_shuffle_epi32 (dk, 0x31); - __m256i const dk2 = _mm256_mul_epu32 (d2, k1); - __m256i const dk2h= _mm256_slli_epi64 (dk2, 32); - - xacc[i] = _mm256_add_epi64(dk1, dk2h); - } } - } - -#elif (XXH_VECTOR == XXH_SSE2) - - { XXH_ALIGN(16) __m128i* const xacc = (__m128i*) acc; - const __m128i* const xkey = (const __m128i *) key; /* not really aligned, just for ptr arithmetic */ - const __m128i k1 = _mm_set1_epi32((int)PRIME32_1); - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(__m128i); i++) { - __m128i data = xacc[i]; - __m128i const shifted = _mm_srli_epi64(data, 47); - data = _mm_xor_si128(data, shifted); - - { __m128i const k = _mm_loadu_si128 (xkey+i); - __m128i const dk = _mm_xor_si128 (data,k); - - __m128i const dk1 = _mm_mul_epu32 (dk,k1); - - __m128i const d2 = _mm_shuffle_epi32 (dk, 0x31); - __m128i const dk2 = _mm_mul_epu32 (d2,k1); - __m128i const dk2h= _mm_slli_epi64(dk2, 32); - - xacc[i] = _mm_add_epi64(dk1, dk2h); - } } - } - -#elif (XXH_VECTOR == XXH_NEON) - - assert(((size_t)acc) & 15 == 0); - - { uint64x2_t* const xacc = (uint64x2_t*) acc; - uint32_t const* const xkey = (uint32_t const*) key; - uint32x2_t const prime = vdup_n_u32 (PRIME32_1); - - size_t i; - for (i=0; i < STRIPE_LEN/sizeof(uint64x2_t); i++) { - /* data_vec = xacc[i] ^ (xacc[i] >> 47); */ - uint64x2_t const acc_vec = xacc[i]; - uint64x2_t const shifted = vshrq_n_u64 (acc_vec, 47); - uint64x2_t const data_vec = veorq_u64 (acc_vec, shifted); - - /* key_vec = xkey[i]; */ - uint32x4_t const key_vec = vld1q_u32 (xkey + (i * 4)); - /* data_key = data_vec ^ key_vec; */ - uint32x4_t const data_key = veorq_u32 (vreinterpretq_u32_u64(data_vec), key_vec); - /* shuffled = { data_key[0, 2], data_key[1, 3] }; */ - uint32x2x2_t const shuffled = vzip_u32 (vget_low_u32(data_key), vget_high_u32(data_key)); - - /* data_key *= PRIME32_1 */ - - /* prod_hi = (data_key >> 32) * PRIME32_1; */ - uint64x2_t const prod_hi = vmull_u32 (shuffled.val[1], prime); - /* xacc[i] = prod_hi << 32; */ - xacc[i] = vshlq_n_u64(prod_hi, 32); - /* xacc[i] += (prod_hi & 0xFFFFFFFF) * PRIME32_1; */ - xacc[i] = vmlal_u32(xacc[i], shuffled.val[0], prime); - } } - -#elif (XXH_VECTOR == XXH_VSX) - - U64x2* const xacc = (U64x2*) acc; - const U64x2* const xkey = (const U64x2*) key; - /* constants */ - U64x2 const v32 = { 32, 32 }; - U64x2 const v47 = { 47, 47 }; - U32x4 const prime = { PRIME32_1, PRIME32_1, PRIME32_1, PRIME32_1 }; - size_t i; - - for (i = 0; i < STRIPE_LEN / sizeof(U64x2); i++) { - U64x2 const acc_vec = xacc[i]; - U64x2 const data_vec = acc_vec ^ (acc_vec >> v47); - /* key_vec = xkey[i]; */ -#ifdef __BIG_ENDIAN__ - /* swap 32-bit words */ - U64x2 const key_vec = vec_rl(vec_vsx_ld(0, xkey + i), v32); -#else - U64x2 const key_vec = vec_vsx_ld(0, xkey + i); -#endif - U64x2 const data_key = data_vec ^ key_vec; - - /* data_key *= PRIME32_1 */ - - /* prod_lo = ((U64x2)data_key & 0xFFFFFFFF) * ((U64x2)prime & 0xFFFFFFFF); */ - U64x2 const prod_lo = XXH_vsxMultOdd((U32x4)data_key, prime); - /* prod_hi = ((U64x2)data_key >> 32) * ((U64x2)prime >> 32); */ - U64x2 const prod_hi = XXH_vsxMultEven((U32x4)data_key, prime); - xacc[i] = prod_lo + (prod_hi << v32); - } - -#else /* scalar variant of Scrambler - universal */ - - XXH_ALIGN(32) U64* const xacc = (U64*) acc; /* presumed aligned on 32-bytes boundaries, little hint for the auto-vectorizer */ - const char* const xkey = (const char*) key; /* no alignment restriction */ - int i; - assert((((size_t)acc) & 31) == 0); - - for (i=0; i < (int)ACC_NB; i++) { - U64 const key64 = XXH_readLE64(xkey + 8*i); - U64 acc64 = xacc[i]; - acc64 ^= acc64 >> 47; - acc64 ^= key64; - acc64 *= PRIME32_1; - xacc[i] = acc64; - } - -#endif -} - -/* assumption : nbStripes will not overflow secret size */ -XXH_FORCE_INLINE void -XXH3_accumulate(U64* restrict acc, const void* restrict data, - const void* restrict secret, size_t nbStripes) -{ - size_t n; - /* Clang doesn't unroll this loop without the pragma. Unrolling can be up to 1.4x faster. - * note from @aras-p : this unroll statement is actually detrimental for WASM. - * need to find a detection macro to exclude this case. */ -#if defined(__clang__) && !defined(__OPTIMIZE_SIZE__) && !defined(__ARM_ARCH) -# pragma clang loop unroll(enable) -#endif - for (n = 0; n < nbStripes; n++ ) { - XXH3_accumulate_512(acc, - (const char*)data + n*STRIPE_LEN, - (const char*)secret + n*XXH_SECRET_CONSUME_RATE); - } -} - -/* note : clang auto-vectorizes well in SS2 mode _if_ this function is `static`, - * and doesn't auto-vectorize it at all if it is `FORCE_INLINE`. - * However, it auto-vectorizes better AVX2 if it is `FORCE_INLINE` - * Pretty much every other modes and compilers prefer `FORCE_INLINE`. - */ -#if defined(__clang__) && (XXH_VECTOR==0) && !defined(__AVX2__) -static void -#else -XXH_FORCE_INLINE void -#endif -XXH3_hashLong_internal_loop( U64* restrict acc, - const void* restrict data, size_t len, - const void* restrict secret, size_t secretSize) -{ - size_t const nb_rounds = (secretSize - STRIPE_LEN) / XXH_SECRET_CONSUME_RATE; - size_t const block_len = STRIPE_LEN * nb_rounds; - size_t const nb_blocks = len / block_len; - - size_t n; - - assert(secretSize >= XXH_SECRET_SIZE_MIN); - - for (n = 0; n < nb_blocks; n++) { - XXH3_accumulate(acc, (const char*)data + n*block_len, secret, nb_rounds); - XXH3_scrambleAcc(acc, (const char*)secret + secretSize - STRIPE_LEN); - } - - /* last partial block */ - assert(len > STRIPE_LEN); - { size_t const nbStripes = (len - (block_len * nb_blocks)) / STRIPE_LEN; - assert(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE)); - XXH3_accumulate(acc, (const char*)data + nb_blocks*block_len, secret, nbStripes); - - /* last stripe */ - if (len & (STRIPE_LEN - 1)) { - const void* const p = (const char*)data + len - STRIPE_LEN; -#define XXH_SECRET_LASTACC_START 7 /* do not align on 8, so that secret is different from scrambler */ - XXH3_accumulate_512(acc, p, (const char*)secret + secretSize - STRIPE_LEN - XXH_SECRET_LASTACC_START); - } } -} - -XXH_FORCE_INLINE U64 -XXH3_mix2Accs(const U64* restrict acc, const void* restrict secret) -{ - const U64* const key64 = (const U64*)secret; - return XXH3_mul128_fold64( - acc[0] ^ XXH_readLE64(key64), - acc[1] ^ XXH_readLE64(key64+1) ); -} - -static XXH64_hash_t -XXH3_mergeAccs(const U64* restrict acc, const void* restrict secret, U64 start) -{ - U64 result64 = start; - - result64 += XXH3_mix2Accs(acc+0, (const char*)secret + 0); - result64 += XXH3_mix2Accs(acc+2, (const char*)secret + 16); - result64 += XXH3_mix2Accs(acc+4, (const char*)secret + 32); - result64 += XXH3_mix2Accs(acc+6, (const char*)secret + 48); - - return XXH3_avalanche(result64); -} - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_hashLong_internal(const void* restrict data, size_t len, - const void* restrict secret, size_t secretSize) -{ - XXH_ALIGN(XXH_ACC_ALIGN) U64 acc[ACC_NB] = { PRIME32_3, PRIME64_1, PRIME64_2, PRIME64_3, PRIME64_4, PRIME32_2, PRIME64_5, PRIME32_1 }; - - XXH3_hashLong_internal_loop(acc, data, len, secret, secretSize); - - /* converge into final hash */ - XXH_STATIC_ASSERT(sizeof(acc) == 64); -#define XXH_SECRET_MERGEACCS_START 11 /* do not align on 8, so that secret is different from accumulator */ - assert(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - return XXH3_mergeAccs(acc, (const char*)secret + XXH_SECRET_MERGEACCS_START, (U64)len * PRIME64_1); -} - - -XXH_NO_INLINE XXH64_hash_t /* It's important for performance that XXH3_hashLong is not inlined. Not sure why (uop cache maybe ?), but difference is large and easily measurable */ -XXH3_hashLong_64b_defaultSecret(const void* restrict data, size_t len) -{ - return XXH3_hashLong_internal(data, len, kSecret, sizeof(kSecret)); -} - -XXH_NO_INLINE XXH64_hash_t /* It's important for performance that XXH3_hashLong is not inlined. Not sure why (uop cache maybe ?), but difference is large and easily measurable */ -XXH3_hashLong_64b_withSecret(const void* restrict data, size_t len, const void* restrict secret, size_t secretSize) -{ - return XXH3_hashLong_internal(data, len, secret, secretSize); -} - - -XXH_FORCE_INLINE void XXH_writeLE64(void* dst, U64 v64) -{ - if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64); - memcpy(dst, &v64, sizeof(v64)); -} - -/* XXH3_initKeySeed() : - * destination `customSecret` is presumed allocated and same size as `kSecret`. - */ -XXH_FORCE_INLINE void XXH3_initKeySeed(void* customSecret, U64 seed64) -{ - char* const dst = (char*)customSecret; - const char* const src = (const char*)kSecret; - int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16; - int i; - - XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); - - for (i=0; i < nbRounds; i++) { - XXH_writeLE64(dst + 16*i, XXH_readLE64(src + 16*i) + seed64); - XXH_writeLE64(dst + 16*i + 8, XXH_readLE64(src + 16*i + 8) - seed64); - } -} - - -/* XXH3_hashLong_64b_withSeed() : - * Generate a custom key, - * based on alteration of default kSecret with the seed, - * and then use this key for long mode hashing. - * This operation is decently fast but nonetheless costs a little bit of time. - * Try to avoid it whenever possible (typically when seed==0). - */ -XXH_NO_INLINE XXH64_hash_t /* It's important for performance that XXH3_hashLong is not inlined. Not sure why (uop cache maybe ?), but difference is large and easily measurable */ -XXH3_hashLong_64b_withSeed(const void* data, size_t len, XXH64_hash_t seed) -{ - XXH_ALIGN(8) char secret[XXH_SECRET_DEFAULT_SIZE]; - XXH3_initKeySeed(secret, seed); - return XXH3_hashLong_internal(data, len, secret, sizeof(secret)); -} - - -XXH_FORCE_INLINE U64 XXH3_mix16B(const void* restrict data, const void* restrict key, U64 seed64) -{ - const U64* const key64 = (const U64*)key; - U64 const ll1 = XXH_readLE64(data); - U64 const ll2 = XXH_readLE64((const BYTE*)data+8); - return XXH3_mul128_fold64( - ll1 ^ (XXH_readLE64(key64) + seed64), - ll2 ^ (XXH_readLE64(key64+1) - seed64) ) ; -} - - -XXH_FORCE_INLINE XXH64_hash_t -XXH3_len_17to128_64b(const void* restrict data, size_t len, const void* restrict secret, size_t secretSize, XXH64_hash_t seed) -{ - const BYTE* const p = (const BYTE*)data; - const char* const key = (const char*)secret; - - assert(secretSize >= XXH_SECRET_SIZE_MIN); (void)secretSize; - assert(16 < len && len <= 128); - - { U64 acc = len * PRIME64_1; - if (len > 32) { - if (len > 64) { - if (len > 96) { - acc += XXH3_mix16B(p+48, key+96, seed); - acc += XXH3_mix16B(p+len-64, key+112, seed); - } - acc += XXH3_mix16B(p+32, key+64, seed); - acc += XXH3_mix16B(p+len-48, key+80, seed); - } - acc += XXH3_mix16B(p+16, key+32, seed); - acc += XXH3_mix16B(p+len-32, key+48, seed); - } - acc += XXH3_mix16B(p+0, key+0, seed); - acc += XXH3_mix16B(p+len-16, key+16, seed); - - return XXH3_avalanche(acc); - } -} - - -/* === Public entry point === */ - -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len) -{ - if (len <= 16) return XXH3_len_0to16_64b(data, len, kSecret, 0); - if (len > 128) return XXH3_hashLong_64b_defaultSecret(data, len); - return XXH3_len_17to128_64b(data, len, kSecret, sizeof(kSecret), 0); -} - -XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize) -{ - assert(secretSize >= XXH_SECRET_SIZE_MIN); - assert(((size_t)secret % 8) == 0); - /* if an action must be taken should `secret` conditions not be respected, - * it should be done here. - * For now, it's a contract pre-condition. - * Adding a check and a branch here would cost performance at every hash */ - if (len <= 16) return XXH3_len_0to16_64b(data, len, secret, 0); - if (len > 128) return XXH3_hashLong_64b_withSecret(data, len, secret, secretSize); - return XXH3_len_17to128_64b(data, len, secret, secretSize, 0); -} - -XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed) -{ - /* note : opened question : would it be faster to - * route to XXH3_64bits_withSecret_internal() - * when `seed == 0` ? - * This would add a branch though. - * Maybe do it into XXH3_hashLong_64b_withSeed() instead, - * since that's where it matters */ - if (len <= 16) return XXH3_len_0to16_64b(data, len, kSecret, seed); - if (len > 128) return XXH3_hashLong_64b_withSeed(data, len, seed); - return XXH3_len_17to128_64b(data, len, kSecret, sizeof(kSecret), seed); -} - -/* === XXH3 streaming === */ - -XXH_PUBLIC_API XXH3_state_t* XXH3_64bits_createState(void) -{ - return (XXH3_state_t*)XXH_malloc(sizeof(XXH3_state_t)); -} - -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_freeState(XXH3_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH_PUBLIC_API void -XXH3_64bits_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state) -{ - memcpy(dst_state, src_state, sizeof(*dst_state)); -} - -static void -XXH3_64bits_reset_internal(XXH3_state_t* statePtr, - XXH64_hash_t seed, - const void* secret, size_t secretSize) -{ - assert(statePtr != NULL); - memset(statePtr, 0, sizeof(*statePtr)); - statePtr->acc[0] = PRIME32_3; - statePtr->acc[1] = PRIME64_1; - statePtr->acc[2] = PRIME64_2; - statePtr->acc[3] = PRIME64_3; - statePtr->acc[4] = PRIME64_4; - statePtr->acc[5] = PRIME32_2; - statePtr->acc[6] = PRIME64_5; - statePtr->acc[7] = PRIME32_1; - statePtr->seed = seed; - assert(secret != NULL); - statePtr->secret = secret; - assert(secretSize >= XXH_SECRET_SIZE_MIN); - statePtr->secretLimit = (XXH32_hash_t)(secretSize - STRIPE_LEN); - statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset(XXH3_state_t* statePtr) -{ - if (statePtr == NULL) return XXH_ERROR; - XXH3_64bits_reset_internal(statePtr, 0, kSecret, XXH_SECRET_DEFAULT_SIZE); - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) -{ - if (statePtr == NULL) return XXH_ERROR; - XXH3_64bits_reset_internal(statePtr, 0, secret, secretSize); - if (secret == NULL) return XXH_ERROR; - if (secretSize < XXH_SECRET_SIZE_MIN) return XXH_ERROR; - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) -{ - if (statePtr == NULL) return XXH_ERROR; - XXH3_64bits_reset_internal(statePtr, seed, kSecret, XXH_SECRET_DEFAULT_SIZE); - XXH3_initKeySeed(statePtr->customSecret, seed); - statePtr->secret = statePtr->customSecret; - return XXH_OK; -} - -static void -XXH3_64bits_consumeStripes( U64* acc, - XXH32_hash_t* nbStripesSoFarPtr, XXH32_hash_t nbStripesPerBlock, - const void* data, size_t totalStripes, - const void* secret, size_t secretLimit) -{ - assert(*nbStripesSoFarPtr < nbStripesPerBlock); - if (nbStripesPerBlock - *nbStripesSoFarPtr <= totalStripes) { - /* need a scrambling operation */ - size_t const nbStripes = nbStripesPerBlock - *nbStripesSoFarPtr; - XXH3_accumulate(acc, data, (const char*)secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes); - XXH3_scrambleAcc(acc, (const char*)secret + secretLimit); - XXH3_accumulate(acc, (const char*)data + nbStripes * STRIPE_LEN, secret, totalStripes - nbStripes); - *nbStripesSoFarPtr = (XXH32_hash_t)(totalStripes - nbStripes); - } else { - XXH3_accumulate(acc, data, (const char*)secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, totalStripes); - *nbStripesSoFarPtr += (XXH32_hash_t)totalStripes; - } -} - -XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len) -{ - if (input==NULL) -#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) - return XXH_OK; -#else - return XXH_ERROR; -#endif - - { const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - - state->totalLen += len; - - if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) { /* fill in tmp buffer */ - XXH_memcpy(state->buffer + state->bufferedSize, input, len); - state->bufferedSize += (XXH32_hash_t)len; - return XXH_OK; - } - /* input now > XXH3_INTERNALBUFFER_SIZE */ - - #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / STRIPE_LEN) - XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % STRIPE_LEN == 0); /* clean multiple */ - - if (state->bufferedSize) { /* some data within internal buffer: fill then consume it */ - size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize; - XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize); - p += loadSize; - XXH3_64bits_consumeStripes(state->acc, - &state->nbStripesSoFar, state->nbStripesPerBlock, - state->buffer, XXH3_INTERNALBUFFER_STRIPES, - state->secret, state->secretLimit); - } - - /* consume input by full buffer quantities */ - if (p+XXH3_INTERNALBUFFER_SIZE <= bEnd) { - const BYTE* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE; - do { - XXH3_64bits_consumeStripes(state->acc, - &state->nbStripesSoFar, state->nbStripesPerBlock, - p, XXH3_INTERNALBUFFER_STRIPES, - state->secret, state->secretLimit); - p += XXH3_INTERNALBUFFER_SIZE; - } while (p<=limit); - } - - if (p < bEnd) { /* some remaining input data : buffer it */ - XXH_memcpy(state->buffer, p, (size_t)(bEnd-p)); - state->bufferedSize = (XXH32_hash_t)(bEnd-p); - } - } - - return XXH_OK; -} - - -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) -{ - if (state->totalLen > XXH3_INTERNALBUFFER_SIZE) { - XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[ACC_NB]; - memcpy(acc, state->acc, sizeof(acc)); /* digest locally, state remains unaltered, and can continue ingesting more data afterwards */ - if (state->bufferedSize >= STRIPE_LEN) { - size_t const totalNbStripes = state->bufferedSize / STRIPE_LEN; - XXH32_hash_t nbStripesSoFar = state->nbStripesSoFar; - XXH3_64bits_consumeStripes(acc, - &nbStripesSoFar, state->nbStripesPerBlock, - state->buffer, totalNbStripes, - state->secret, state->secretLimit); - if (state->bufferedSize % STRIPE_LEN) { /* one last partial stripe */ - XXH3_accumulate_512(acc, state->buffer + state->bufferedSize - STRIPE_LEN, (const char*)state->secret + state->secretLimit - XXH_SECRET_LASTACC_START); - } - } else { /* bufferedSize < STRIPE_LEN */ - if (state->bufferedSize) { /* one last stripe */ - char lastStripe[STRIPE_LEN]; - size_t const catchupSize = STRIPE_LEN - state->bufferedSize; - memcpy(lastStripe, (const char*)state->buffer + sizeof(state->buffer) - catchupSize, catchupSize); - memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize); - XXH3_accumulate_512(acc, lastStripe, (const char*)state->secret + state->secretLimit - XXH_SECRET_LASTACC_START); - } } - return XXH3_mergeAccs(acc, (const char*)state->secret + XXH_SECRET_MERGEACCS_START, (U64)state->totalLen * PRIME64_1); - } - /* len <= XXH3_INTERNALBUFFER_SIZE : short code */ - if (state->seed) - return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); - return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen), state->secret, state->secretLimit + STRIPE_LEN); -} - - -/* ========================================== - * XXH3 128 bits (=> XXH128) - * ========================================== */ - -XXH_FORCE_INLINE XXH128_hash_t -XXH3_len_1to3_128b(const void* data, size_t len, const void* keyPtr, XXH64_hash_t seed) -{ - assert(data != NULL); - assert(len > 0 && len <= 3); - assert(keyPtr != NULL); - { const U32* const key32 = (const U32*) keyPtr; - BYTE const c1 = ((const BYTE*)data)[0]; - BYTE const c2 = ((const BYTE*)data)[len >> 1]; - BYTE const c3 = ((const BYTE*)data)[len - 1]; - U32 const l1 = (U32)(c1) + ((U32)(c2) << 8); - U32 const l2 = (U32)(len) + ((U32)(c3) << 2); - U64 const ll11 = XXH_mult32to64((unsigned int)(l1 + seed + key32[0]), (unsigned int)(l2 + key32[1])); - U64 const ll12 = XXH_mult32to64((unsigned int)(l1 + key32[2]), (unsigned int)(l2 - seed + key32[3])); - XXH128_hash_t const h128 = { XXH3_avalanche(ll11), XXH3_avalanche(ll12) }; - return h128; - } -} - - -XXH_FORCE_INLINE XXH128_hash_t -XXH3_len_4to8_128b(const void* data, size_t len, const void* keyPtr, XXH64_hash_t seed) -{ - assert(data != NULL); - assert(len >= 4 && len <= 8); - { const U32* const key32 = (const U32*) keyPtr; - U32 const l1 = XXH_readLE32(data) + (U32)seed + key32[0]; - U32 const l2 = XXH_readLE32((const BYTE*)data + len - 4) + (U32)(seed >> 32) + key32[1]; - U64 const acc1 = len + l1 + ((U64)l2 << 32) + XXH_mult32to64(l1, l2); - U64 const acc2 = len*PRIME64_1 + l1*PRIME64_2 + l2*PRIME64_3; - { XXH128_hash_t const h128 = { XXH3_avalanche(acc1), XXH3_avalanche(acc2) }; - return h128; - } - } -} - -XXH_FORCE_INLINE XXH128_hash_t -XXH3_len_9to16_128b(const void* data, size_t len, const void* keyPtr, XXH64_hash_t seed) -{ - assert(data != NULL); - assert(key != NULL); - assert(len >= 9 && len <= 16); - { const U64* const key64 = (const U64*) keyPtr; - U64 acc1 = PRIME64_1 * ((U64)len + seed); - U64 acc2 = PRIME64_2 * ((U64)len - seed); - U64 const ll1 = XXH_readLE64(data); - U64 const ll2 = XXH_readLE64((const BYTE*)data + len - 8); - acc1 += XXH3_mul128_fold64(ll1 + XXH_readLE64(key64+0), ll2 + XXH_readLE64(key64+1)); - acc2 += XXH3_mul128_fold64(ll1 + XXH_readLE64(key64+2), ll2 + XXH_readLE64(key64+3)); - { XXH128_hash_t const h128 = { XXH3_avalanche(acc1), XXH3_avalanche(acc2) }; - return h128; - } - } -} - -XXH_FORCE_INLINE XXH128_hash_t -XXH3_len_0to16_128b(const void* data, size_t len, XXH64_hash_t seed) -{ - assert(data != NULL); - assert(len <= 16); - { if (len > 8) return XXH3_len_9to16_128b(data, len, kSecret, seed); - if (len >= 4) return XXH3_len_4to8_128b(data, len, kSecret, seed); - if (len) return XXH3_len_1to3_128b(data, len, kSecret, seed); - { XXH128_hash_t const h128 = { seed, (XXH64_hash_t)0 - seed }; - return h128; - } - } -} - -XXH_NO_INLINE XXH128_hash_t /* It's important for performance that XXH3_hashLong is not inlined. Not sure why (uop cache maybe ?), but difference is large and easily measurable */ -XXH3_hashLong_128b(const void* data, size_t len, XXH64_hash_t seed) -{ - XXH_ALIGN(64) U64 acc[ACC_NB] = { seed, PRIME64_1, PRIME64_2, PRIME64_3, PRIME64_4, PRIME64_5, (U64)0 - seed, 0 }; - assert(len > 128); - - XXH3_hashLong_internal_loop(acc, data, len, kSecret, sizeof(kSecret)); - - /* converge into final hash */ - assert(sizeof(acc) == 64); - { U64 const low64 = XXH3_mergeAccs(acc, kSecret, (U64)len * PRIME64_1); - U64 const high64 = XXH3_mergeAccs(acc, kSecret+16, ((U64)len+1) * PRIME64_2); - XXH128_hash_t const h128 = { low64, high64 }; - return h128; - } -} - -XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed) -{ - if (len <= 16) return XXH3_len_0to16_128b(data, len, seed); - - { U64 acc1 = PRIME64_1 * (len + seed); - U64 acc2 = 0; - const BYTE* const p = (const BYTE*)data; - const char* const key = (const char*)kSecret; - if (len > 32) { - if (len > 64) { - if (len > 96) { - if (len > 128) return XXH3_hashLong_128b(data, len, seed); - - acc1 += XXH3_mix16B(p+48, key+96, seed); - acc2 += XXH3_mix16B(p+len-64, key+112, seed); - } - - acc1 += XXH3_mix16B(p+32, key+64, seed); - acc2 += XXH3_mix16B(p+len-48, key+80, seed); - } - - acc1 += XXH3_mix16B(p+16, key+32, seed); - acc2 += XXH3_mix16B(p+len-32, key+48, seed); - } - - acc1 += XXH3_mix16B(p+0, key+0, seed); - acc2 += XXH3_mix16B(p+len-16, key+16, seed); - - { U64 const part1 = acc1 + acc2; - U64 const part2 = (acc1 * PRIME64_3) + (acc2 * PRIME64_4) + ((len - seed) * PRIME64_2); - XXH128_hash_t const h128 = { XXH3_avalanche(part1), (XXH64_hash_t)0 - XXH3_avalanche(part2) }; - return h128; - } - } -} - - -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len) -{ - return XXH3_128bits_withSeed(data, len, 0); -} - - -XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed) -{ - return XXH3_128bits_withSeed(data, len, seed); -} - - -#ifdef UNDEF_NDEBUG -# undef NDEBUG -#endif - -#endif /* XXH3_H */ diff --git a/src/common/util/xxhash.c b/src/common/util/xxhash.c deleted file mode 100644 index 00b5aefb3..000000000 --- a/src/common/util/xxhash.c +++ /dev/null @@ -1,1024 +0,0 @@ -/* -* xxHash - Fast Hash algorithm -* Copyright (C) 2012-2016, Yann Collet -* -* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* You can contact the author at : -* - xxHash homepage: http://www.xxhash.com -* - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - - -/* ************************************* -* Tuning parameters -***************************************/ -/*!XXH_FORCE_MEMORY_ACCESS : - * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. - * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. - * The below switch allow to select different access method for improved performance. - * Method 0 (default) : use `memcpy()`. Safe and portable. - * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). - * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. - * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. - * It can generate buggy code on targets which do not support unaligned memory accesses. - * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) - * See http://stackoverflow.com/a/32095106/646947 for details. - * Prefer these methods in priority order (0 > 1 > 2) - */ -#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ - || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ - || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define XXH_FORCE_MEMORY_ACCESS 2 -# elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ - || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ - || defined(__ARM_ARCH_7S__) )) -# define XXH_FORCE_MEMORY_ACCESS 1 -# endif -#endif - -/*!XXH_ACCEPT_NULL_INPUT_POINTER : - * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault. - * When this macro is enabled, xxHash actively checks input for null pointer. - * It it is, result for null input pointers is the same as a null-length input. - */ -#ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */ -# define XXH_ACCEPT_NULL_INPUT_POINTER 0 -#endif - -/*!XXH_FORCE_ALIGN_CHECK : - * This is a minor performance trick, only useful with lots of very small keys. - * It means : check for aligned/unaligned input. - * The check costs one initial branch per hash; - * set it to 0 when the input is guaranteed to be aligned, - * or when alignment doesn't matter for performance. - */ -#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ -# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_FORCE_ALIGN_CHECK 0 -# else -# define XXH_FORCE_ALIGN_CHECK 1 -# endif -#endif - - -/* ************************************* -* Includes & Memory related functions -***************************************/ -/*! Modify the local functions below should you wish to use some other memory routines -* for malloc(), free() */ -#include -static void* XXH_malloc(size_t s) { return malloc(s); } -static void XXH_free (void* p) { free(p); } -/*! and for memcpy() */ -#include -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } - -#include /* assert */ - -#define XXH_STATIC_LINKING_ONLY -#include "xxhash.h" - - -/* ************************************* -* Compiler Specific Options -***************************************/ -#ifdef _MSC_VER /* Visual Studio */ -# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -# define XXH_FORCE_INLINE static __forceinline -# define XXH_NO_INLINE static __declspec(noinline) -#else -# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# ifdef __GNUC__ -# define XXH_FORCE_INLINE static inline __attribute__((always_inline)) -# define XXH_NO_INLINE static __attribute__((noinline)) -# else -# define XXH_FORCE_INLINE static inline -# define XXH_NO_INLINE static -# endif -# else -# define XXH_FORCE_INLINE static -# define XXH_NO_INLINE static -# endif /* __STDC_VERSION__ */ -#endif - - -/* ************************************* -* Basic Types -***************************************/ -#ifndef MEM_MODULE -# if !defined (__VMS) \ - && (defined (__cplusplus) \ - || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef uint32_t U32; -# else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef unsigned int U32; -# endif -#endif - - -/* === Memory access === */ - -#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) - -/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ -static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } - -#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -typedef union { U32 u32; } __attribute__((packed)) unalign; -static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } - -#else - -/* portable and safe solution. Generally efficient. - * see : http://stackoverflow.com/a/32095106/646947 - */ -static U32 XXH_read32(const void* memPtr) -{ - U32 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ - - -/* === Endianess === */ -typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; - -/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ -#ifndef XXH_CPU_LITTLE_ENDIAN -static int XXH_isLittleEndian(void) -{ - const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ - return one.c[0]; -} -# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian() -#endif - - - - -/* **************************************** -* Compiler-specific Functions and Macros -******************************************/ -#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ -#if defined(_MSC_VER) -# define XXH_rotl32(x,r) _rotl(x,r) -# define XXH_rotl64(x,r) _rotl64(x,r) -#else -# define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) -# define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r)))) -#endif - -#if defined(_MSC_VER) /* Visual Studio */ -# define XXH_swap32 _byteswap_ulong -#elif XXH_GCC_VERSION >= 403 -# define XXH_swap32 __builtin_bswap32 -#else -static U32 XXH_swap32 (U32 x) -{ - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff ); -} -#endif - - -/* *************************** -* Memory reads -*****************************/ -typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; - -XXH_FORCE_INLINE U32 XXH_readLE32(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); -} - -static U32 XXH_readBE32(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); -} - -XXH_FORCE_INLINE U32 -XXH_readLE32_align(const void* ptr, XXH_alignment align) -{ - if (align==XXH_unaligned) { - return XXH_readLE32(ptr); - } else { - return XXH_CPU_LITTLE_ENDIAN ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); - } -} - - -/* ************************************* -* Macros -***************************************/ -#define XXH_STATIC_ASSERT(c) { enum { XXH_sa = 1/(int)(!!(c)) }; } /* use after variable declarations */ -XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } - - -/* ******************************************************************* -* 32-bit hash functions -*********************************************************************/ -static const U32 PRIME32_1 = 2654435761U; /* 0b10011110001101110111100110110001 */ -static const U32 PRIME32_2 = 2246822519U; /* 0b10000101111010111100101001110111 */ -static const U32 PRIME32_3 = 3266489917U; /* 0b11000010101100101010111000111101 */ -static const U32 PRIME32_4 = 668265263U; /* 0b00100111110101001110101100101111 */ -static const U32 PRIME32_5 = 374761393U; /* 0b00010110010101100110011110110001 */ - -static U32 XXH32_round(U32 acc, U32 input) -{ - acc += input * PRIME32_2; - acc = XXH_rotl32(acc, 13); - acc *= PRIME32_1; -#if defined(__GNUC__) && defined(__SSE4_1__) && !defined(XXH_ENABLE_AUTOVECTORIZE) - /* UGLY HACK: - * This inline assembly hack forces acc into a normal register. This is the - * only thing that prevents GCC and Clang from autovectorizing the XXH32 loop - * (pragmas and attributes don't work for some resason) without globally - * disabling SSE4.1. - * - * The reason we want to avoid vectorization is because despite working on - * 4 integers at a time, there are multiple factors slowing XXH32 down on - * SSE4: - * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on newer chips!) - * making it slightly slower to multiply four integers at once compared to four - * integers independently. Even when pmulld was fastest, Sandy/Ivy Bridge, it is - * still not worth it to go into SSE just to multiply unless doing a long operation. - * - * - Four instructions are required to rotate, - * movqda tmp, v // not required with VEX encoding - * pslld tmp, 13 // tmp <<= 13 - * psrld v, 19 // x >>= 19 - * por v, tmp // x |= tmp - * compared to one for scalar: - * roll v, 13 // reliably fast across the board - * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason - * - * - Instruction level parallelism is actually more beneficial here because the - * SIMD actually serializes this operation: While v1 is rotating, v2 can load data, - * while v3 can multiply. SSE forces them to operate together. - * - * How this hack works: - * __asm__("" // Declare an assembly block but don't declare any instructions - * : // However, as an Input/Output Operand, - * "+r" // constrain a read/write operand (+) as a general purpose register (r). - * (acc) // and set acc as the operand - * ); - * - * Because of the 'r', the compiler has promised that seed will be in a - * general purpose register and the '+' says that it will be 'read/write', - * so it has to assume it has changed. It is like volatile without all the - * loads and stores. - * - * Since the argument has to be in a normal register (not an SSE register), - * each time XXH32_round is called, it is impossible to vectorize. */ - __asm__("" : "+r" (acc)); -#endif - return acc; -} - -/* mix all bits */ -static U32 XXH32_avalanche(U32 h32) -{ - h32 ^= h32 >> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - return(h32); -} - -#define XXH_get32bits(p) XXH_readLE32_align(p, align) - -static U32 -XXH32_finalize(U32 h32, const void* ptr, size_t len, XXH_alignment align) - -{ - const BYTE* p = (const BYTE*)ptr; - -#define PROCESS1 \ - h32 += (*p++) * PRIME32_5; \ - h32 = XXH_rotl32(h32, 11) * PRIME32_1 ; - -#define PROCESS4 \ - h32 += XXH_get32bits(p) * PRIME32_3; \ - p+=4; \ - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; - - switch(len&15) /* or switch(bEnd - p) */ - { - case 12: PROCESS4; - /* fallthrough */ - case 8: PROCESS4; - /* fallthrough */ - case 4: PROCESS4; - return XXH32_avalanche(h32); - - case 13: PROCESS4; - /* fallthrough */ - case 9: PROCESS4; - /* fallthrough */ - case 5: PROCESS4; - PROCESS1; - return XXH32_avalanche(h32); - - case 14: PROCESS4; - /* fallthrough */ - case 10: PROCESS4; - /* fallthrough */ - case 6: PROCESS4; - PROCESS1; - PROCESS1; - return XXH32_avalanche(h32); - - case 15: PROCESS4; - /* fallthrough */ - case 11: PROCESS4; - /* fallthrough */ - case 7: PROCESS4; - /* fallthrough */ - case 3: PROCESS1; - /* fallthrough */ - case 2: PROCESS1; - /* fallthrough */ - case 1: PROCESS1; - /* fallthrough */ - case 0: return XXH32_avalanche(h32); - } - assert(0); - return h32; /* reaching this point is deemed impossible */ -} - -XXH_FORCE_INLINE U32 -XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U32 h32; - -#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) - if (p==NULL) { - len=0; - bEnd=p=(const BYTE*)(size_t)16; - } -#endif - - if (len>=16) { - const BYTE* const limit = bEnd - 15; - U32 v1 = seed + PRIME32_1 + PRIME32_2; - U32 v2 = seed + PRIME32_2; - U32 v3 = seed + 0; - U32 v4 = seed - PRIME32_1; - - do { - v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4; - v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4; - v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4; - v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4; - } while (p < limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) - + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } else { - h32 = seed + PRIME32_5; - } - - h32 += (U32)len; - - return XXH32_finalize(h32, p, len&15, align); -} - - -XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH32_state_t state; - XXH32_reset(&state, seed); - XXH32_update(&state, input, len); - return XXH32_digest(&state); - -#else - - if (XXH_FORCE_ALIGN_CHECK) { - if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ - return XXH32_endian_align(input, len, seed, XXH_aligned); - } } - - return XXH32_endian_align(input, len, seed, XXH_unaligned); -#endif -} - - - -/*====== Hash streaming ======*/ - -XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) -{ - return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); -} -XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) -{ - memcpy(dstState, srcState, sizeof(*dstState)); -} - -XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed) -{ - XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)); - state.v1 = seed + PRIME32_1 + PRIME32_2; - state.v2 = seed + PRIME32_2; - state.v3 = seed + 0; - state.v4 = seed - PRIME32_1; - /* do not write into reserved, planned to be removed in a future version */ - memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); - return XXH_OK; -} - - -XXH_PUBLIC_API XXH_errorcode -XXH32_update(XXH32_state_t* state, const void* input, size_t len) -{ - if (input==NULL) -#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) - return XXH_OK; -#else - return XXH_ERROR; -#endif - - { const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - - state->total_len_32 += (XXH32_hash_t)len; - state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); - - if (state->memsize + len < 16) { /* fill in tmp buffer */ - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); - state->memsize += (XXH32_hash_t)len; - return XXH_OK; - } - - if (state->memsize) { /* some data left from previous update */ - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); - { const U32* p32 = state->mem32; - state->v1 = XXH32_round(state->v1, XXH_readLE32(p32)); p32++; - state->v2 = XXH32_round(state->v2, XXH_readLE32(p32)); p32++; - state->v3 = XXH32_round(state->v3, XXH_readLE32(p32)); p32++; - state->v4 = XXH32_round(state->v4, XXH_readLE32(p32)); - } - p += 16-state->memsize; - state->memsize = 0; - } - - if (p <= bEnd-16) { - const BYTE* const limit = bEnd - 16; - U32 v1 = state->v1; - U32 v2 = state->v2; - U32 v3 = state->v3; - U32 v4 = state->v4; - - do { - v1 = XXH32_round(v1, XXH_readLE32(p)); p+=4; - v2 = XXH32_round(v2, XXH_readLE32(p)); p+=4; - v3 = XXH32_round(v3, XXH_readLE32(p)); p+=4; - v4 = XXH32_round(v4, XXH_readLE32(p)); p+=4; - } while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) { - XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); - } - } - - return XXH_OK; -} - - -XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state) -{ - U32 h32; - - if (state->large_len) { - h32 = XXH_rotl32(state->v1, 1) - + XXH_rotl32(state->v2, 7) - + XXH_rotl32(state->v3, 12) - + XXH_rotl32(state->v4, 18); - } else { - h32 = state->v3 /* == seed */ + PRIME32_5; - } - - h32 += state->total_len_32; - - return XXH32_finalize(h32, state->mem32, state->memsize, XXH_aligned); -} - - -/*====== Canonical representation ======*/ - -/*! Default XXH result types are basic unsigned 32 and 64 bits. -* The canonical representation follows human-readable write convention, aka big-endian (large digits first). -* These functions allow transformation of hash result into and from its canonical format. -* This way, hash values can be written into a file or buffer, remaining comparable across different systems. -*/ - -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) -{ - XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); - if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); - memcpy(dst, &hash, sizeof(*dst)); -} - -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) -{ - return XXH_readBE32(src); -} - - -#ifndef XXH_NO_LONG_LONG - -/* ******************************************************************* -* 64-bit hash functions -*********************************************************************/ - -/*====== Memory access ======*/ - -#ifndef MEM_MODULE -# define MEM_MODULE -# if !defined (__VMS) \ - && (defined (__cplusplus) \ - || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint64_t U64; -# else - /* if compiler doesn't support unsigned long long, replace by another 64-bit type */ - typedef unsigned long long U64; -# endif -#endif - - -#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) - -/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ -static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } - -#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64; -static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; } - -#else - -/* portable and safe solution. Generally efficient. - * see : http://stackoverflow.com/a/32095106/646947 - */ - -static U64 XXH_read64(const void* memPtr) -{ - U64 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ - -#if defined(_MSC_VER) /* Visual Studio */ -# define XXH_swap64 _byteswap_uint64 -#elif XXH_GCC_VERSION >= 403 -# define XXH_swap64 __builtin_bswap64 -#else -static U64 XXH_swap64 (U64 x) -{ - return ((x << 56) & 0xff00000000000000ULL) | - ((x << 40) & 0x00ff000000000000ULL) | - ((x << 24) & 0x0000ff0000000000ULL) | - ((x << 8) & 0x000000ff00000000ULL) | - ((x >> 8) & 0x00000000ff000000ULL) | - ((x >> 24) & 0x0000000000ff0000ULL) | - ((x >> 40) & 0x000000000000ff00ULL) | - ((x >> 56) & 0x00000000000000ffULL); -} -#endif - -XXH_FORCE_INLINE U64 XXH_readLE64(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); -} - -static U64 XXH_readBE64(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); -} - -XXH_FORCE_INLINE U64 -XXH_readLE64_align(const void* ptr, XXH_alignment align) -{ - if (align==XXH_unaligned) - return XXH_readLE64(ptr); - else - return XXH_CPU_LITTLE_ENDIAN ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); -} - - -/*====== xxh64 ======*/ - -static const U64 PRIME64_1 = 11400714785074694791ULL; /* 0b1001111000110111011110011011000110000101111010111100101010000111 */ -static const U64 PRIME64_2 = 14029467366897019727ULL; /* 0b1100001010110010101011100011110100100111110101001110101101001111 */ -static const U64 PRIME64_3 = 1609587929392839161ULL; /* 0b0001011001010110011001111011000110011110001101110111100111111001 */ -static const U64 PRIME64_4 = 9650029242287828579ULL; /* 0b1000010111101011110010100111011111000010101100101010111001100011 */ -static const U64 PRIME64_5 = 2870177450012600261ULL; /* 0b0010011111010100111010110010111100010110010101100110011111000101 */ - -static U64 XXH64_round(U64 acc, U64 input) -{ - acc += input * PRIME64_2; - acc = XXH_rotl64(acc, 31); - acc *= PRIME64_1; - return acc; -} - -static U64 XXH64_mergeRound(U64 acc, U64 val) -{ - val = XXH64_round(0, val); - acc ^= val; - acc = acc * PRIME64_1 + PRIME64_4; - return acc; -} - -static U64 XXH64_avalanche(U64 h64) -{ - h64 ^= h64 >> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - return h64; -} - - -#define XXH_get64bits(p) XXH_readLE64_align(p, align) - -static U64 -XXH64_finalize(U64 h64, const void* ptr, size_t len, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)ptr; - -#define PROCESS1_64 \ - h64 ^= (*p++) * PRIME64_5; \ - h64 = XXH_rotl64(h64, 11) * PRIME64_1; - -#define PROCESS4_64 \ - h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; \ - p+=4; \ - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - -#define PROCESS8_64 { \ - U64 const k1 = XXH64_round(0, XXH_get64bits(p)); \ - p+=8; \ - h64 ^= k1; \ - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \ -} - - switch(len&31) { - case 24: PROCESS8_64; - /* fallthrough */ - case 16: PROCESS8_64; - /* fallthrough */ - case 8: PROCESS8_64; - return XXH64_avalanche(h64); - - case 28: PROCESS8_64; - /* fallthrough */ - case 20: PROCESS8_64; - /* fallthrough */ - case 12: PROCESS8_64; - /* fallthrough */ - case 4: PROCESS4_64; - return XXH64_avalanche(h64); - - case 25: PROCESS8_64; - /* fallthrough */ - case 17: PROCESS8_64; - /* fallthrough */ - case 9: PROCESS8_64; - PROCESS1_64; - return XXH64_avalanche(h64); - - case 29: PROCESS8_64; - /* fallthrough */ - case 21: PROCESS8_64; - /* fallthrough */ - case 13: PROCESS8_64; - /* fallthrough */ - case 5: PROCESS4_64; - PROCESS1_64; - return XXH64_avalanche(h64); - - case 26: PROCESS8_64; - /* fallthrough */ - case 18: PROCESS8_64; - /* fallthrough */ - case 10: PROCESS8_64; - PROCESS1_64; - PROCESS1_64; - return XXH64_avalanche(h64); - - case 30: PROCESS8_64; - /* fallthrough */ - case 22: PROCESS8_64; - /* fallthrough */ - case 14: PROCESS8_64; - /* fallthrough */ - case 6: PROCESS4_64; - PROCESS1_64; - PROCESS1_64; - return XXH64_avalanche(h64); - - case 27: PROCESS8_64; - /* fallthrough */ - case 19: PROCESS8_64; - /* fallthrough */ - case 11: PROCESS8_64; - PROCESS1_64; - PROCESS1_64; - PROCESS1_64; - return XXH64_avalanche(h64); - - case 31: PROCESS8_64; - /* fallthrough */ - case 23: PROCESS8_64; - /* fallthrough */ - case 15: PROCESS8_64; - /* fallthrough */ - case 7: PROCESS4_64; - /* fallthrough */ - case 3: PROCESS1_64; - /* fallthrough */ - case 2: PROCESS1_64; - /* fallthrough */ - case 1: PROCESS1_64; - /* fallthrough */ - case 0: return XXH64_avalanche(h64); - } - - /* impossible to reach */ - assert(0); - return 0; /* unreachable, but some compilers complain without it */ -} - -XXH_FORCE_INLINE U64 -XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U64 h64; - -#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) - if (p==NULL) { - len=0; - bEnd=p=(const BYTE*)(size_t)32; - } -#endif - - if (len>=32) { - const BYTE* const limit = bEnd - 32; - U64 v1 = seed + PRIME64_1 + PRIME64_2; - U64 v2 = seed + PRIME64_2; - U64 v3 = seed + 0; - U64 v4 = seed - PRIME64_1; - - do { - v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; - v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; - v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; - v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; - } while (p<=limit); - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - h64 = XXH64_mergeRound(h64, v1); - h64 = XXH64_mergeRound(h64, v2); - h64 = XXH64_mergeRound(h64, v3); - h64 = XXH64_mergeRound(h64, v4); - - } else { - h64 = seed + PRIME64_5; - } - - h64 += (U64) len; - - return XXH64_finalize(h64, p, len, align); -} - - -XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, unsigned long long seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH64_state_t state; - XXH64_reset(&state, seed); - XXH64_update(&state, input, len); - return XXH64_digest(&state); - -#else - - if (XXH_FORCE_ALIGN_CHECK) { - if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ - return XXH64_endian_align(input, len, seed, XXH_aligned); - } } - - return XXH64_endian_align(input, len, seed, XXH_unaligned); - -#endif -} - -/*====== Hash Streaming ======*/ - -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) -{ - return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); -} -XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState) -{ - memcpy(dstState, srcState, sizeof(*dstState)); -} - -XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed) -{ - XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)); - state.v1 = seed + PRIME64_1 + PRIME64_2; - state.v2 = seed + PRIME64_2; - state.v3 = seed + 0; - state.v4 = seed - PRIME64_1; - /* do not write into reserved, might be removed in a future version */ - memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode -XXH64_update (XXH64_state_t* state, const void* input, size_t len) -{ - if (input==NULL) -#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) - return XXH_OK; -#else - return XXH_ERROR; -#endif - - { const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - - state->total_len += len; - - if (state->memsize + len < 32) { /* fill in tmp buffer */ - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) { /* tmp buffer is full */ - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); - state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0)); - state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1)); - state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2)); - state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3)); - p += 32-state->memsize; - state->memsize = 0; - } - - if (p+32 <= bEnd) { - const BYTE* const limit = bEnd - 32; - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - do { - v1 = XXH64_round(v1, XXH_readLE64(p)); p+=8; - v2 = XXH64_round(v2, XXH_readLE64(p)); p+=8; - v3 = XXH64_round(v3, XXH_readLE64(p)); p+=8; - v4 = XXH64_round(v4, XXH_readLE64(p)); p+=8; - } while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) { - XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); - } - } - - return XXH_OK; -} - - -XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* state) -{ - U64 h64; - - if (state->total_len >= 32) { - U64 const v1 = state->v1; - U64 const v2 = state->v2; - U64 const v3 = state->v3; - U64 const v4 = state->v4; - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - h64 = XXH64_mergeRound(h64, v1); - h64 = XXH64_mergeRound(h64, v2); - h64 = XXH64_mergeRound(h64, v3); - h64 = XXH64_mergeRound(h64, v4); - } else { - h64 = state->v3 /*seed*/ + PRIME64_5; - } - - h64 += (U64) state->total_len; - - return XXH64_finalize(h64, state->mem64, (size_t)state->total_len, XXH_aligned); -} - - -/*====== Canonical representation ======*/ - -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) -{ - XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); - if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); - memcpy(dst, &hash, sizeof(*dst)); -} - -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) -{ - return XXH_readBE64(src); -} - - - -/* ********************************************************************* -* XXH3 -* New generation hash designed for speed on small keys and vectorization -************************************************************************ */ - -#include "xxh3.h" - - -#endif /* XXH_NO_LONG_LONG */ diff --git a/src/common/util/xxhash.h b/src/common/util/xxhash.h deleted file mode 100644 index d01ac4091..000000000 --- a/src/common/util/xxhash.h +++ /dev/null @@ -1,512 +0,0 @@ -/* - xxHash - Extremely Fast Hash algorithm - Header File - Copyright (C) 2012-2016, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - You can contact the author at : - - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - -/* Notice extracted from xxHash homepage : - -xxHash is an extremely fast Hash algorithm, running at RAM speed limits. -It also successfully passes all tests from the SMHasher suite. - -Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) - -Name Speed Q.Score Author -xxHash 5.4 GB/s 10 -CrapWow 3.2 GB/s 2 Andrew -MumurHash 3a 2.7 GB/s 10 Austin Appleby -SpookyHash 2.0 GB/s 10 Bob Jenkins -SBox 1.4 GB/s 9 Bret Mulvey -Lookup3 1.2 GB/s 9 Bob Jenkins -SuperFastHash 1.2 GB/s 1 Paul Hsieh -CityHash64 1.05 GB/s 10 Pike & Alakuijala -FNV 0.55 GB/s 5 Fowler, Noll, Vo -CRC32 0.43 GB/s 9 -MD5-32 0.33 GB/s 10 Ronald L. Rivest -SHA1-32 0.28 GB/s 10 - -Q.Score is a measure of quality of the hash function. -It depends on successfully passing SMHasher test set. -10 is a perfect score. - -A 64-bit version, named XXH64, is available since r35. -It offers much better speed, but for 64-bit applications only. -Name Speed on 64 bits Speed on 32 bits -XXH64 13.8 GB/s 1.9 GB/s -XXH32 6.8 GB/s 6.0 GB/s -*/ - -#ifndef XXHASH_H_5627135585666179 -#define XXHASH_H_5627135585666179 1 - -#if defined (__cplusplus) -extern "C" { -#endif - - -/* **************************** -* Definitions -******************************/ -#include /* size_t */ -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; - - -/* **************************** - * API modifier - ******************************/ -/** XXH_INLINE_ALL (and XXH_PRIVATE_API) - * This is useful to include xxhash functions in `static` mode - * in order to inline them, and remove their symbol from the public list. - * Inlining can offer dramatic performance improvement on small keys. - * Methodology : - * #define XXH_INLINE_ALL - * #include "xxhash.h" - * `xxhash.c` is automatically included. - * It's not useful to compile and link it as a separate module. - */ -#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) -# ifndef XXH_STATIC_LINKING_ONLY -# define XXH_STATIC_LINKING_ONLY -# endif -# if defined(__GNUC__) -# define XXH_PUBLIC_API static __inline __attribute__((unused)) -# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define XXH_PUBLIC_API static inline -# elif defined(_MSC_VER) -# define XXH_PUBLIC_API static __inline -# else - /* this version may generate warnings for unused static functions */ -# define XXH_PUBLIC_API static -# endif -#else -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) -# ifdef XXH_EXPORT -# define XXH_PUBLIC_API __declspec(dllexport) -# elif XXH_IMPORT -# define XXH_PUBLIC_API __declspec(dllimport) -# endif -# else -# define XXH_PUBLIC_API /* do nothing */ -# endif -#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ - -/*! XXH_NAMESPACE, aka Namespace Emulation : - * - * If you want to include _and expose_ xxHash functions from within your own library, - * but also want to avoid symbol collisions with other libraries which may also include xxHash, - * - * you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library - * with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values). - * - * Note that no change is required within the calling program as long as it includes `xxhash.h` : - * regular symbol name will be automatically translated by this header. - */ -#ifdef XXH_NAMESPACE -# define XXH_CAT(A,B) A##B -# define XXH_NAME2(A,B) XXH_CAT(A,B) -# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) -# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) -# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) -# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) -# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) -# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) -# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) -# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) -# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) -# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) -# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) -# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) -# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) -# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) -# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) -# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) -# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) -# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) -# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) -#endif - - -/* ************************************* -* Version -***************************************/ -#define XXH_VERSION_MAJOR 0 -#define XXH_VERSION_MINOR 7 -#define XXH_VERSION_RELEASE 0 -#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) -XXH_PUBLIC_API unsigned XXH_versionNumber (void); - - -/*-********************************************************************** -* 32-bit hash -************************************************************************/ -#if !defined (__VMS) \ - && (defined (__cplusplus) \ - || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint32_t XXH32_hash_t; -#else - typedef unsigned int XXH32_hash_t; -#endif - -/*! XXH32() : - Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input". - The memory between input & input+length must be valid (allocated and read-accessible). - "seed" can be used to alter the result predictably. - Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */ -XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed); - -/*====== Streaming ======*/ -typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ -XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); -XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state); - -XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed); -XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); - -/* - * Streaming functions generate the xxHash of an input provided in multiple segments. - * Note that, for small input, they are slower than single-call functions, due to state management. - * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. - * - * XXH state must first be allocated, using XXH*_createState() . - * - * Start a new hash by initializing state with a seed, using XXH*_reset(). - * - * Then, feed the hash state by calling XXH*_update() as many times as necessary. - * The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. - * - * Finally, a hash value can be produced anytime, by using XXH*_digest(). - * This function returns the nn-bits hash as an int or long long. - * - * It's still possible to continue inserting input into the hash state after a digest, - * and generate some new hashes later on, by calling again XXH*_digest(). - * - * When done, free XXH state space if it was allocated dynamically. - */ - -/*====== Canonical representation ======*/ - -typedef struct { unsigned char digest[4]; } XXH32_canonical_t; -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); - -/* Default result type for XXH functions are primitive unsigned 32 and 64 bits. - * The canonical representation uses human-readable write convention, aka big-endian (large digits first). - * These functions allow transformation of hash result into and from its canonical format. - * This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. - */ - - -#ifndef XXH_NO_LONG_LONG -/*-********************************************************************** -* 64-bit hash -************************************************************************/ -#if !defined (__VMS) \ - && (defined (__cplusplus) \ - || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint64_t XXH64_hash_t; -#else - typedef unsigned long long XXH64_hash_t; -#endif - -/*! XXH64() : - Calculate the 64-bit hash of sequence of length "len" stored at memory address "input". - "seed" can be used to alter the result predictably. - This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark). -*/ -XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed); - -/*====== Streaming ======*/ -typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); -XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state); - -XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); - -/*====== Canonical representation ======*/ -typedef struct { unsigned char digest[8]; } XXH64_canonical_t; -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); - - -#endif /* XXH_NO_LONG_LONG */ - - - -#ifdef XXH_STATIC_LINKING_ONLY - -/* ================================================================================================ - This section contains declarations which are not guaranteed to remain stable. - They may change in future versions, becoming incompatible with a different version of the library. - These declarations should only be used with static linking. - Never use them in association with dynamic linking ! -=================================================================================================== */ - -/* These definitions are only present to allow - * static allocation of XXH state, on stack or in a struct for example. - * Never **ever** use members directly. */ - -struct XXH32_state_s { - XXH32_hash_t total_len_32; - XXH32_hash_t large_len; - XXH32_hash_t v1; - XXH32_hash_t v2; - XXH32_hash_t v3; - XXH32_hash_t v4; - XXH32_hash_t mem32[4]; - XXH32_hash_t memsize; - XXH32_hash_t reserved; /* never read nor write, might be removed in a future version */ -}; /* typedef'd to XXH32_state_t */ - -#ifndef XXH_NO_LONG_LONG /* remove 64-bit support */ -struct XXH64_state_s { - XXH64_hash_t total_len; - XXH64_hash_t v1; - XXH64_hash_t v2; - XXH64_hash_t v3; - XXH64_hash_t v4; - XXH64_hash_t mem64[4]; - XXH32_hash_t memsize; - XXH32_hash_t reserved[2]; /* never read nor write, might be removed in a future version */ -}; /* typedef'd to XXH64_state_t */ -#endif /* XXH_NO_LONG_LONG */ - - -/*-********************************************************************** -* XXH3 -* New experimental hash -************************************************************************/ -#ifndef XXH_NO_LONG_LONG - - -/* ============================================ - * XXH3 is a new hash algorithm, - * featuring vastly improved speed performance - * for both small and large inputs. - * See full speed analysis at : http://fastcompression.blogspot.com/2019/03/presenting-xxh3.html - * In general, expect XXH3 to run about ~2x faster on large inputs, - * and >3x faster on small ones, though exact difference depend on platform. - * - * The algorithm is portable, will generate the same hash on all platforms. - * It benefits greatly from vectorization units, but does not require it. - * - * XXH3 offers 2 variants, _64bits and _128bits. - * When only 64 bits are needed, prefer calling the _64bits variant : - * it reduces the amount of mixing, resulting in faster speed on small inputs. - * It's also generally simpler to manipulate a scalar return type than a struct. - * - * The XXH3 algorithm is still considered experimental. - * Produced results can still change between versions. - * It's possible to use it for ephemeral data, but avoid storing long-term values for later re-use. - * - * The API currently supports one-shot hashing only. - * The full version will include streaming capability, and canonical representation. - * - * There are still a number of opened questions that community can influence during the experimental period. - * I'm trying to list a few of them below, though don't consider this list as complete. - * - * - 128-bits output type : currently defined as a structure of 2 64-bits fields. - * That's because 128-bit values do not exist in C standard. - * Note that it means that, at byte level, result is not identical depending on endianess. - * However, at field level, they are identical on all platforms. - * The canonical representation will solve the issue of identical byte-level representation across platforms, - * which is necessary for serialization. - * Would there be a better representation for a 128-bit hash result ? - * Are the names of the inner 64-bit fields important ? Should they be changed ? - * - * - Canonical representation : for the 64-bit variant, canonical representation is the same as XXH64() (aka big-endian). - * What should it be for the 128-bit variant ? - * Since it's no longer a scalar value, big-endian representation is no longer an obvious choice. - * One possibility : represent it as the concatenation of two 64-bits canonical representation (aka 2x big-endian) - * Another one : represent it in the same order as natural order in the struct for little-endian platforms. - * Less consistent with existing convention for XXH32/XXH64, but may be more natural for little-endian platforms. - * - * - Associated functions for 128-bit hash : simple things, such as checking if 2 hashes are equal, become more difficult with struct. - * Granted, it's not terribly difficult to create a comparator, but it's still a workload. - * Would it be beneficial to declare and define a comparator function for XXH128_hash_t ? - * Are there other operations on XXH128_hash_t which would be desirable ? - * - * - Seed type for 128-bits variant : currently, it's a single 64-bit value, like the 64-bit variant. - * It could be argued that it's more logical to offer a 128-bit seed input parameter for a 128-bit hash. - * Although it's also more difficult to use, since it requires to declare and pass a structure instead of a value. - * It would either replace current choice, or add a new one. - * Farmhash, for example, offers both variants (the 128-bits seed variant is called `doubleSeed`). - * If both 64-bit and 128-bit seeds are possible, which variant should be called XXH128 ? - * - * - Result for len==0 : Currently, the result of hashing a zero-length input is `0`. - * It seems okay as a return value when using all "default" secret and seed (it used to be a request for XXH32/XXH64). - * But is it still fine to return `0` when secret or seed are non-default ? - * Are there use case which would depend on a different hash result when the secret is different ? - */ - -#ifdef XXH_NAMESPACE -# define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits) -# define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret) -# define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed) - -# define XXH3_64bits_createState XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_createState) -# define XXH3_64bits_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_freeState) -# define XXH3_64bits_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_copyState) -# define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset) -# define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed) -# define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret) -# define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update) -# define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest) - -# define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits) -# define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed) -# define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128) -#endif - -/* XXH3_64bits() : - * default 64-bit variant, using default secret and default seed of 0. - * it's also the fastest one. */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len); - -/* XXH3_64bits_withSecret() : - * It's possible to provide any blob of bytes as a "secret" to generate the hash. - * This makes it more difficult for an external actor to prepare an intentional collision. - * The secret *must* be large enough (>= XXH_SECRET_SIZE_MIN). - * It should consist of random bytes. - * Avoid repeating same character, and especially avoid swathes of \0. - * Avoid repeating sequences of bytes within the secret. - * Failure to respect these conditions will result in a bad quality hash. - */ -#define XXH_SECRET_SIZE_MIN 136 -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); - -/* XXH3_64bits_withSeed() : - * This variant generates on the fly a custom secret, - * based on the default secret, altered using the `seed` value. - * While this operation is decently fast, note that it's not completely free. - * note : seed==0 produces same results as XXH3_64bits() */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); - - -/* streaming 64-bit */ - -#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11+ */ -# include -# define XXH_ALIGN(n) alignas(n) -#elif defined(__GNUC__) -# define XXH_ALIGN(n) __attribute__ ((aligned(n))) -#elif defined(_MSC_VER) -# define XXH_ALIGN(n) __declspec(align(n)) -#else -# define XXH_ALIGN(n) /* disabled */ -#endif - -typedef struct XXH3_state_s XXH3_state_t; - -#define XXH3_SECRET_DEFAULT_SIZE 192 /* minimum XXH_SECRET_SIZE_MIN */ -#define XXH3_INTERNALBUFFER_SIZE 128 -struct XXH3_state_s { - XXH_ALIGN(64) XXH64_hash_t acc[8]; - XXH_ALIGN(64) char customSecret[XXH3_SECRET_DEFAULT_SIZE]; /* used to store a custom secret generated from the seed. Makes state larger. Design might change */ - XXH_ALIGN(64) char buffer[XXH3_INTERNALBUFFER_SIZE]; - const void* secret; - XXH32_hash_t bufferedSize; - XXH32_hash_t nbStripesPerBlock; - XXH32_hash_t nbStripesSoFar; - XXH32_hash_t reserved32; - XXH32_hash_t reserved32_2; - XXH32_hash_t secretLimit; - XXH64_hash_t totalLen; - XXH64_hash_t seed; - XXH64_hash_t reserved64; -}; /* typedef'd to XXH3_state_t */ - -/* Streaming requires state maintenance. - * This operation costs memory and cpu. - * As a consequence, streaming is slower than one-shot hashing. - * For better performance, prefer using one-short functions anytime possible. */ - -XXH_PUBLIC_API XXH3_state_t* XXH3_64bits_createState(void); -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_freeState(XXH3_state_t* statePtr); -XXH_PUBLIC_API void XXH3_64bits_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state); - -/* XXH3_64bits_reset() : - * initialize with default parameters. - * result will be equivalent to `XXH3_64bits()` */ -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr); -/* XXH3_64bits_reset_withSeed() : - * generate a custom secret from `seed`, and store it into state. - * digest will be equivalent to `XXH3_64bits_withSeed()` */ -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); -/* XXH3_64bits_reset_withSecret() : - * `secret` is referenced, and must outlive the hash streaming session. - * secretSize must be >= XXH_SECRET_SIZE_MIN. - */ -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); - -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr); - - -/* 128-bit */ - -typedef struct { - XXH64_hash_t low64; - XXH64_hash_t high64; -} XXH128_hash_t; - -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len); -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); /* == XXH128() */ -XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed); - - - -#endif /* XXH_NO_LONG_LONG */ - - -/*-********************************************************************** -* XXH_INLINE_ALL -************************************************************************/ -#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) -# include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */ -#endif - - - -#endif /* XXH_STATIC_LINKING_ONLY */ - - -#if defined (__cplusplus) -} -#endif - -#endif /* XXHASH_H_5627135585666179 */ diff --git a/src/core/kernel/init/CxbxKrnl.cpp b/src/core/kernel/init/CxbxKrnl.cpp index f5a5dcc59..f5eec0556 100644 --- a/src/core/kernel/init/CxbxKrnl.cpp +++ b/src/core/kernel/init/CxbxKrnl.cpp @@ -54,7 +54,7 @@ #include "core\kernel\memory-manager\VMManager.h" #include "CxbxDebugger.h" #include "common/util/cliConfig.hpp" -#include "common/util/xxhash.h" +#include "xxhash.h" #include "common/ReserveAddressRanges.h" #include "common/xbox/Types.hpp"