17ec681f3Smrg/* 27ec681f3Smrg xxHash - Extremely Fast Hash algorithm 37ec681f3Smrg Header File 47ec681f3Smrg Copyright (C) 2012-2016, Yann Collet. 57ec681f3Smrg 67ec681f3Smrg BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 77ec681f3Smrg 87ec681f3Smrg Redistribution and use in source and binary forms, with or without 97ec681f3Smrg modification, are permitted provided that the following conditions are 107ec681f3Smrg met: 117ec681f3Smrg 127ec681f3Smrg * Redistributions of source code must retain the above copyright 137ec681f3Smrg notice, this list of conditions and the following disclaimer. 147ec681f3Smrg * Redistributions in binary form must reproduce the above 157ec681f3Smrg copyright notice, this list of conditions and the following disclaimer 167ec681f3Smrg in the documentation and/or other materials provided with the 177ec681f3Smrg distribution. 187ec681f3Smrg 197ec681f3Smrg THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 207ec681f3Smrg "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 217ec681f3Smrg LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 227ec681f3Smrg A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 237ec681f3Smrg OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 247ec681f3Smrg SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 257ec681f3Smrg LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 267ec681f3Smrg DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 277ec681f3Smrg THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 287ec681f3Smrg (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 297ec681f3Smrg OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 307ec681f3Smrg 317ec681f3Smrg You can contact the author at : 327ec681f3Smrg - xxHash source repository : https://github.com/Cyan4973/xxHash 337ec681f3Smrg*/ 347ec681f3Smrg 357ec681f3Smrg/* Notice extracted from xxHash homepage : 367ec681f3Smrg 377ec681f3SmrgxxHash is an extremely fast Hash algorithm, running at RAM speed limits. 387ec681f3SmrgIt also successfully passes all tests from the SMHasher suite. 397ec681f3Smrg 407ec681f3SmrgComparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) 417ec681f3Smrg 427ec681f3SmrgName Speed Q.Score Author 437ec681f3SmrgxxHash 5.4 GB/s 10 447ec681f3SmrgCrapWow 3.2 GB/s 2 Andrew 457ec681f3SmrgMumurHash 3a 2.7 GB/s 10 Austin Appleby 467ec681f3SmrgSpookyHash 2.0 GB/s 10 Bob Jenkins 477ec681f3SmrgSBox 1.4 GB/s 9 Bret Mulvey 487ec681f3SmrgLookup3 1.2 GB/s 9 Bob Jenkins 497ec681f3SmrgSuperFastHash 1.2 GB/s 1 Paul Hsieh 507ec681f3SmrgCityHash64 1.05 GB/s 10 Pike & Alakuijala 517ec681f3SmrgFNV 0.55 GB/s 5 Fowler, Noll, Vo 527ec681f3SmrgCRC32 0.43 GB/s 9 537ec681f3SmrgMD5-32 0.33 GB/s 10 Ronald L. Rivest 547ec681f3SmrgSHA1-32 0.28 GB/s 10 557ec681f3Smrg 567ec681f3SmrgQ.Score is a measure of quality of the hash function. 577ec681f3SmrgIt depends on successfully passing SMHasher test set. 587ec681f3Smrg10 is a perfect score. 597ec681f3Smrg 607ec681f3SmrgNote : SMHasher's CRC32 implementation is not the fastest one. 617ec681f3SmrgOther speed-oriented implementations can be faster, 627ec681f3Smrgespecially in combination with PCLMUL instruction : 637ec681f3Smrghttp://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735 647ec681f3Smrg 657ec681f3SmrgA 64-bit version, named XXH64, is available since r35. 667ec681f3SmrgIt offers much better speed, but for 64-bit applications only. 677ec681f3SmrgName Speed on 64 bits Speed on 32 bits 687ec681f3SmrgXXH64 13.8 GB/s 1.9 GB/s 697ec681f3SmrgXXH32 6.8 GB/s 6.0 GB/s 707ec681f3Smrg*/ 717ec681f3Smrg 727ec681f3Smrg/* Mesa leaves strict aliasing on in the compiler, and this code likes to 737ec681f3Smrg * dereference the passed in data as u32*, which means that the compiler is 747ec681f3Smrg * free to move the u32 read before the write of the struct members being 757ec681f3Smrg * hashed, and in practice it did in freedreno. Forcing these two things 767ec681f3Smrg * prevents it. 777ec681f3Smrg */ 787ec681f3Smrg#define XXH_FORCE_ALIGN_CHECK 0 797ec681f3Smrg#define XXH_FORCE_MEMORY_ACCESS 0 807ec681f3Smrg 817ec681f3Smrg#include "util/compiler.h" /* for FALLTHROUGH */ 827ec681f3Smrg 837ec681f3Smrg#if defined (__cplusplus) 847ec681f3Smrgextern "C" { 857ec681f3Smrg#endif 867ec681f3Smrg 877ec681f3Smrg 887ec681f3Smrg#ifndef XXHASH_H_5627135585666179 897ec681f3Smrg#define XXHASH_H_5627135585666179 1 907ec681f3Smrg 917ec681f3Smrg/* **************************** 927ec681f3Smrg * API modifier 937ec681f3Smrg ******************************/ 947ec681f3Smrg/** XXH_INLINE_ALL (and XXH_PRIVATE_API) 957ec681f3Smrg * This build macro includes xxhash functions in `static` mode 967ec681f3Smrg * in order to inline them, and remove their symbol from the public list. 977ec681f3Smrg * Inlining offers great performance improvement on small keys, 987ec681f3Smrg * and dramatic ones when length is expressed as a compile-time constant. 997ec681f3Smrg * See https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html . 1007ec681f3Smrg * Methodology : 1017ec681f3Smrg * #define XXH_INLINE_ALL 1027ec681f3Smrg * #include "xxhash.h" 1037ec681f3Smrg * `xxhash.c` is automatically included. 1047ec681f3Smrg * It's not useful to compile and link it as a separate object. 1057ec681f3Smrg */ 1067ec681f3Smrg#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) 1077ec681f3Smrg# ifndef XXH_STATIC_LINKING_ONLY 1087ec681f3Smrg# define XXH_STATIC_LINKING_ONLY 1097ec681f3Smrg# endif 1107ec681f3Smrg# if defined(__GNUC__) 1117ec681f3Smrg# define XXH_PUBLIC_API static __inline __attribute__((unused)) 1127ec681f3Smrg# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) 1137ec681f3Smrg# define XXH_PUBLIC_API static inline 1147ec681f3Smrg# elif defined(_MSC_VER) 1157ec681f3Smrg# define XXH_PUBLIC_API static __inline 1167ec681f3Smrg# else 1177ec681f3Smrg /* this version may generate warnings for unused static functions */ 1187ec681f3Smrg# define XXH_PUBLIC_API static 1197ec681f3Smrg# endif 1207ec681f3Smrg#else 1217ec681f3Smrg# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) 1227ec681f3Smrg# ifdef XXH_EXPORT 1237ec681f3Smrg# define XXH_PUBLIC_API __declspec(dllexport) 1247ec681f3Smrg# elif XXH_IMPORT 1257ec681f3Smrg# define XXH_PUBLIC_API __declspec(dllimport) 1267ec681f3Smrg# endif 1277ec681f3Smrg# else 1287ec681f3Smrg# define XXH_PUBLIC_API /* do nothing */ 1297ec681f3Smrg# endif 1307ec681f3Smrg#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ 1317ec681f3Smrg 1327ec681f3Smrg/*! XXH_NAMESPACE, aka Namespace Emulation : 1337ec681f3Smrg * 1347ec681f3Smrg * If you want to include _and expose_ xxHash functions from within your own library, 1357ec681f3Smrg * but also want to avoid symbol collisions with other libraries which may also include xxHash, 1367ec681f3Smrg * 1377ec681f3Smrg * you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library 1387ec681f3Smrg * with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values). 1397ec681f3Smrg * 1407ec681f3Smrg * Note that no change is required within the calling program as long as it includes `xxhash.h` : 1417ec681f3Smrg * regular symbol name will be automatically translated by this header. 1427ec681f3Smrg */ 1437ec681f3Smrg#ifdef XXH_NAMESPACE 1447ec681f3Smrg# define XXH_CAT(A,B) A##B 1457ec681f3Smrg# define XXH_NAME2(A,B) XXH_CAT(A,B) 1467ec681f3Smrg# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) 1477ec681f3Smrg# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) 1487ec681f3Smrg# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) 1497ec681f3Smrg# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) 1507ec681f3Smrg# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) 1517ec681f3Smrg# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) 1527ec681f3Smrg# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) 1537ec681f3Smrg# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) 1547ec681f3Smrg# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) 1557ec681f3Smrg# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) 1567ec681f3Smrg# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) 1577ec681f3Smrg# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) 1587ec681f3Smrg# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) 1597ec681f3Smrg# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) 1607ec681f3Smrg# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) 1617ec681f3Smrg# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) 1627ec681f3Smrg# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) 1637ec681f3Smrg# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) 1647ec681f3Smrg# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) 1657ec681f3Smrg#endif 1667ec681f3Smrg 1677ec681f3Smrg 1687ec681f3Smrg/* ************************************* 1697ec681f3Smrg* Version 1707ec681f3Smrg***************************************/ 1717ec681f3Smrg#define XXH_VERSION_MAJOR 0 1727ec681f3Smrg#define XXH_VERSION_MINOR 7 1737ec681f3Smrg#define XXH_VERSION_RELEASE 2 1747ec681f3Smrg#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) 1757ec681f3SmrgXXH_PUBLIC_API unsigned XXH_versionNumber (void); 1767ec681f3Smrg 1777ec681f3Smrg 1787ec681f3Smrg/* **************************** 1797ec681f3Smrg* Definitions 1807ec681f3Smrg******************************/ 1817ec681f3Smrg#include <stddef.h> /* size_t */ 1827ec681f3Smrgtypedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; 1837ec681f3Smrg 1847ec681f3Smrg 1857ec681f3Smrg/*-********************************************************************** 1867ec681f3Smrg* 32-bit hash 1877ec681f3Smrg************************************************************************/ 1887ec681f3Smrg#if !defined (__VMS) \ 1897ec681f3Smrg && (defined (__cplusplus) \ 1907ec681f3Smrg || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) 1917ec681f3Smrg# include <stdint.h> 1927ec681f3Smrg typedef uint32_t XXH32_hash_t; 1937ec681f3Smrg#else 1947ec681f3Smrg# include <limits.h> 1957ec681f3Smrg# if UINT_MAX == 0xFFFFFFFFUL 1967ec681f3Smrg typedef unsigned int XXH32_hash_t; 1977ec681f3Smrg# else 1987ec681f3Smrg# if ULONG_MAX == 0xFFFFFFFFUL 1997ec681f3Smrg typedef unsigned long XXH32_hash_t; 2007ec681f3Smrg# else 2017ec681f3Smrg# error "unsupported platform : need a 32-bit type" 2027ec681f3Smrg# endif 2037ec681f3Smrg# endif 2047ec681f3Smrg#endif 2057ec681f3Smrg 2067ec681f3Smrg/*! XXH32() : 2077ec681f3Smrg Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input". 2087ec681f3Smrg The memory between input & input+length must be valid (allocated and read-accessible). 2097ec681f3Smrg "seed" can be used to alter the result predictably. 2107ec681f3Smrg Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */ 2117ec681f3SmrgXXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); 2127ec681f3Smrg 2137ec681f3Smrg/******* Streaming *******/ 2147ec681f3Smrg 2157ec681f3Smrg/* 2167ec681f3Smrg * Streaming functions generate the xxHash value from an incrememtal input. 2177ec681f3Smrg * This method is slower than single-call functions, due to state management. 2187ec681f3Smrg * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. 2197ec681f3Smrg * 2207ec681f3Smrg * XXH state must first be allocated, using XXH*_createState() . 2217ec681f3Smrg * 2227ec681f3Smrg * Start a new hash by initializing state with a seed, using XXH*_reset(). 2237ec681f3Smrg * 2247ec681f3Smrg * Then, feed the hash state by calling XXH*_update() as many times as necessary. 2257ec681f3Smrg * The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. 2267ec681f3Smrg * 2277ec681f3Smrg * Finally, a hash value can be produced anytime, by using XXH*_digest(). 2287ec681f3Smrg * This function returns the nn-bits hash as an int or long long. 2297ec681f3Smrg * 2307ec681f3Smrg * It's still possible to continue inserting input into the hash state after a digest, 2317ec681f3Smrg * and generate some new hash values later on, by invoking again XXH*_digest(). 2327ec681f3Smrg * 2337ec681f3Smrg * When done, release the state, using XXH*_freeState(). 2347ec681f3Smrg */ 2357ec681f3Smrg 2367ec681f3Smrgtypedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ 2377ec681f3SmrgXXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); 2387ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); 2397ec681f3SmrgXXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state); 2407ec681f3Smrg 2417ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); 2427ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); 2437ec681f3SmrgXXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); 2447ec681f3Smrg 2457ec681f3Smrg/******* Canonical representation *******/ 2467ec681f3Smrg 2477ec681f3Smrg/* Default return values from XXH functions are basic unsigned 32 and 64 bits. 2487ec681f3Smrg * This the simplest and fastest format for further post-processing. 2497ec681f3Smrg * However, this leaves open the question of what is the order of bytes, 2507ec681f3Smrg * since little and big endian conventions will write the same number differently. 2517ec681f3Smrg * 2527ec681f3Smrg * The canonical representation settles this issue, 2537ec681f3Smrg * by mandating big-endian convention, 2547ec681f3Smrg * aka, the same convention as human-readable numbers (large digits first). 2557ec681f3Smrg * When writing hash values to storage, sending them over a network, or printing them, 2567ec681f3Smrg * it's highly recommended to use the canonical representation, 2577ec681f3Smrg * to ensure portability across a wider range of systems, present and future. 2587ec681f3Smrg * 2597ec681f3Smrg * The following functions allow transformation of hash values into and from canonical format. 2607ec681f3Smrg */ 2617ec681f3Smrg 2627ec681f3Smrgtypedef struct { unsigned char digest[4]; } XXH32_canonical_t; 2637ec681f3SmrgXXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); 2647ec681f3SmrgXXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); 2657ec681f3Smrg 2667ec681f3Smrg 2677ec681f3Smrg#ifndef XXH_NO_LONG_LONG 2687ec681f3Smrg/*-********************************************************************** 2697ec681f3Smrg* 64-bit hash 2707ec681f3Smrg************************************************************************/ 2717ec681f3Smrg#if !defined (__VMS) \ 2727ec681f3Smrg && (defined (__cplusplus) \ 2737ec681f3Smrg || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) 2747ec681f3Smrg# include <stdint.h> 2757ec681f3Smrg typedef uint64_t XXH64_hash_t; 2767ec681f3Smrg#else 2777ec681f3Smrg /* the following type must have a width of 64-bit */ 2787ec681f3Smrg typedef unsigned long long XXH64_hash_t; 2797ec681f3Smrg#endif 2807ec681f3Smrg 2817ec681f3Smrg/*! XXH64() : 2827ec681f3Smrg * Returns the 64-bit hash of sequence of length @length stored at memory address @input. 2837ec681f3Smrg * @seed can be used to alter the result predictably. 2847ec681f3Smrg * This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark). 2857ec681f3Smrg */ 2867ec681f3SmrgXXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, XXH64_hash_t seed); 2877ec681f3Smrg 2887ec681f3Smrg/******* Streaming *******/ 2897ec681f3Smrgtypedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ 2907ec681f3SmrgXXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); 2917ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); 2927ec681f3SmrgXXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state); 2937ec681f3Smrg 2947ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed); 2957ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); 2967ec681f3SmrgXXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); 2977ec681f3Smrg 2987ec681f3Smrg/******* Canonical representation *******/ 2997ec681f3Smrgtypedef struct { unsigned char digest[8]; } XXH64_canonical_t; 3007ec681f3SmrgXXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); 3017ec681f3SmrgXXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); 3027ec681f3Smrg 3037ec681f3Smrg 3047ec681f3Smrg#endif /* XXH_NO_LONG_LONG */ 3057ec681f3Smrg 3067ec681f3Smrg#endif /* XXHASH_H_5627135585666179 */ 3077ec681f3Smrg 3087ec681f3Smrg 3097ec681f3Smrg 3107ec681f3Smrg#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) 3117ec681f3Smrg#define XXHASH_H_STATIC_13879238742 3127ec681f3Smrg/* ************************************************************************************************ 3137ec681f3Smrg This section contains declarations which are not guaranteed to remain stable. 3147ec681f3Smrg They may change in future versions, becoming incompatible with a different version of the library. 3157ec681f3Smrg These declarations should only be used with static linking. 3167ec681f3Smrg Never use them in association with dynamic linking ! 3177ec681f3Smrg*************************************************************************************************** */ 3187ec681f3Smrg 3197ec681f3Smrg/* These definitions are only present to allow 3207ec681f3Smrg * static allocation of XXH state, on stack or in a struct for example. 3217ec681f3Smrg * Never **ever** use members directly. */ 3227ec681f3Smrg 3237ec681f3Smrgstruct XXH32_state_s { 3247ec681f3Smrg XXH32_hash_t total_len_32; 3257ec681f3Smrg XXH32_hash_t large_len; 3267ec681f3Smrg XXH32_hash_t v1; 3277ec681f3Smrg XXH32_hash_t v2; 3287ec681f3Smrg XXH32_hash_t v3; 3297ec681f3Smrg XXH32_hash_t v4; 3307ec681f3Smrg XXH32_hash_t mem32[4]; 3317ec681f3Smrg XXH32_hash_t memsize; 3327ec681f3Smrg XXH32_hash_t reserved; /* never read nor write, might be removed in a future version */ 3337ec681f3Smrg}; /* typedef'd to XXH32_state_t */ 3347ec681f3Smrg 3357ec681f3Smrg 3367ec681f3Smrg#ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */ 3377ec681f3Smrg 3387ec681f3Smrgstruct XXH64_state_s { 3397ec681f3Smrg XXH64_hash_t total_len; 3407ec681f3Smrg XXH64_hash_t v1; 3417ec681f3Smrg XXH64_hash_t v2; 3427ec681f3Smrg XXH64_hash_t v3; 3437ec681f3Smrg XXH64_hash_t v4; 3447ec681f3Smrg XXH64_hash_t mem64[4]; 3457ec681f3Smrg XXH32_hash_t memsize; 3467ec681f3Smrg XXH32_hash_t reserved32; /* required for padding anyway */ 3477ec681f3Smrg XXH64_hash_t reserved64; /* never read nor write, might be removed in a future version */ 3487ec681f3Smrg}; /* typedef'd to XXH64_state_t */ 3497ec681f3Smrg 3507ec681f3Smrg#endif /* XXH_NO_LONG_LONG */ 3517ec681f3Smrg 3527ec681f3Smrg#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) 3537ec681f3Smrg# define XXH_IMPLEMENTATION 3547ec681f3Smrg#endif 3557ec681f3Smrg 3567ec681f3Smrg#endif /* defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) */ 3577ec681f3Smrg 3587ec681f3Smrg 3597ec681f3Smrg 3607ec681f3Smrg/*-********************************************************************** 3617ec681f3Smrg* xxHash implementation 3627ec681f3Smrg* Functions implementation used to be hosted within xxhash.c . 3637ec681f3Smrg* However, code inlining requires to place implementation in the header file. 3647ec681f3Smrg* As a consequence, xxhash.c used to be included within xxhash.h . 3657ec681f3Smrg* But some build systems don't like *.c inclusions. 3667ec681f3Smrg* So the implementation is now directly integrated within xxhash.h . 3677ec681f3Smrg* Another small advantage is that xxhash.c is no longer required in /includes . 3687ec681f3Smrg************************************************************************/ 3697ec681f3Smrg 3707ec681f3Smrg#if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \ 3717ec681f3Smrg || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387) 3727ec681f3Smrg# define XXH_IMPLEM_13a8737387 3737ec681f3Smrg 3747ec681f3Smrg/* ************************************* 3757ec681f3Smrg* Tuning parameters 3767ec681f3Smrg***************************************/ 3777ec681f3Smrg/*!XXH_FORCE_MEMORY_ACCESS : 3787ec681f3Smrg * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. 3797ec681f3Smrg * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. 3807ec681f3Smrg * The below switch allow to select different access method for improved performance. 3817ec681f3Smrg * Method 0 (default) : use `memcpy()`. Safe and portable. 3827ec681f3Smrg * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). 3837ec681f3Smrg * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. 3847ec681f3Smrg * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. 3857ec681f3Smrg * It can generate buggy code on targets which do not support unaligned memory accesses. 3867ec681f3Smrg * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) 3877ec681f3Smrg * See http://stackoverflow.com/a/32095106/646947 for details. 3887ec681f3Smrg * Prefer these methods in priority order (0 > 1 > 2) 3897ec681f3Smrg */ 3907ec681f3Smrg#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ 3917ec681f3Smrg# if !defined(__clang__) && defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED) && defined(__ARM_ARCH) && (__ARM_ARCH == 6) 3927ec681f3Smrg# define XXH_FORCE_MEMORY_ACCESS 2 3937ec681f3Smrg# elif !defined(__clang__) && ((defined(__INTEL_COMPILER) && !defined(_WIN32)) || \ 3947ec681f3Smrg (defined(__GNUC__) && (defined(__ARM_ARCH) && __ARM_ARCH >= 7))) 3957ec681f3Smrg# define XXH_FORCE_MEMORY_ACCESS 1 3967ec681f3Smrg# endif 3977ec681f3Smrg#endif 3987ec681f3Smrg 3997ec681f3Smrg/*!XXH_ACCEPT_NULL_INPUT_POINTER : 4007ec681f3Smrg * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault. 4017ec681f3Smrg * When this macro is enabled, xxHash actively checks input for null pointer. 4027ec681f3Smrg * It it is, result for null input pointers is the same as a null-length input. 4037ec681f3Smrg */ 4047ec681f3Smrg#ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */ 4057ec681f3Smrg# define XXH_ACCEPT_NULL_INPUT_POINTER 0 4067ec681f3Smrg#endif 4077ec681f3Smrg 4087ec681f3Smrg/*!XXH_FORCE_ALIGN_CHECK : 4097ec681f3Smrg * This is a minor performance trick, only useful with lots of very small keys. 4107ec681f3Smrg * It means : check for aligned/unaligned input. 4117ec681f3Smrg * The check costs one initial branch per hash; 4127ec681f3Smrg * set it to 0 when the input is guaranteed to be aligned, 4137ec681f3Smrg * or when alignment doesn't matter for performance. 4147ec681f3Smrg */ 4157ec681f3Smrg#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ 4167ec681f3Smrg# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) 4177ec681f3Smrg# define XXH_FORCE_ALIGN_CHECK 0 4187ec681f3Smrg# else 4197ec681f3Smrg# define XXH_FORCE_ALIGN_CHECK 1 4207ec681f3Smrg# endif 4217ec681f3Smrg#endif 4227ec681f3Smrg 4237ec681f3Smrg/*!XXH_REROLL: 4247ec681f3Smrg * Whether to reroll XXH32_finalize, and XXH64_finalize, 4257ec681f3Smrg * instead of using an unrolled jump table/if statement loop. 4267ec681f3Smrg * 4277ec681f3Smrg * This is automatically defined on -Os/-Oz on GCC and Clang. */ 4287ec681f3Smrg#ifndef XXH_REROLL 4297ec681f3Smrg# if defined(__OPTIMIZE_SIZE__) 4307ec681f3Smrg# define XXH_REROLL 1 4317ec681f3Smrg# else 4327ec681f3Smrg# define XXH_REROLL 0 4337ec681f3Smrg# endif 4347ec681f3Smrg#endif 4357ec681f3Smrg 4367ec681f3Smrg 4377ec681f3Smrg/* ************************************* 4387ec681f3Smrg* Includes & Memory related functions 4397ec681f3Smrg***************************************/ 4407ec681f3Smrg/*! Modify the local functions below should you wish to use some other memory routines 4417ec681f3Smrg* for malloc(), free() */ 4427ec681f3Smrg#include <stdlib.h> 4437ec681f3Smrgstatic void* XXH_malloc(size_t s) { return malloc(s); } 4447ec681f3Smrgstatic void XXH_free (void* p) { free(p); } 4457ec681f3Smrg/*! and for memcpy() */ 4467ec681f3Smrg#include <string.h> 4477ec681f3Smrgstatic void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } 4487ec681f3Smrg 4497ec681f3Smrg#include <limits.h> /* ULLONG_MAX */ 4507ec681f3Smrg 4517ec681f3Smrg 4527ec681f3Smrg/* ************************************* 4537ec681f3Smrg* Compiler Specific Options 4547ec681f3Smrg***************************************/ 4557ec681f3Smrg#ifdef _MSC_VER /* Visual Studio */ 4567ec681f3Smrg# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ 4577ec681f3Smrg# define XXH_FORCE_INLINE static __forceinline 4587ec681f3Smrg# define XXH_NO_INLINE static __declspec(noinline) 4597ec681f3Smrg#else 4607ec681f3Smrg# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ 4617ec681f3Smrg# ifdef __GNUC__ 4627ec681f3Smrg# define XXH_FORCE_INLINE static inline __attribute__((always_inline)) 4637ec681f3Smrg# define XXH_NO_INLINE static __attribute__((noinline)) 4647ec681f3Smrg# else 4657ec681f3Smrg# define XXH_FORCE_INLINE static inline 4667ec681f3Smrg# define XXH_NO_INLINE static 4677ec681f3Smrg# endif 4687ec681f3Smrg# else 4697ec681f3Smrg# define XXH_FORCE_INLINE static 4707ec681f3Smrg# define XXH_NO_INLINE static 4717ec681f3Smrg# endif /* __STDC_VERSION__ */ 4727ec681f3Smrg#endif 4737ec681f3Smrg 4747ec681f3Smrg 4757ec681f3Smrg 4767ec681f3Smrg/* ************************************* 4777ec681f3Smrg* Debug 4787ec681f3Smrg***************************************/ 4797ec681f3Smrg/* DEBUGLEVEL is expected to be defined externally, 4807ec681f3Smrg * typically through compiler command line. 4817ec681f3Smrg * Value must be a number. */ 4827ec681f3Smrg#ifndef DEBUGLEVEL 4837ec681f3Smrg# define DEBUGLEVEL 0 4847ec681f3Smrg#endif 4857ec681f3Smrg 4867ec681f3Smrg#if (DEBUGLEVEL>=1) 4877ec681f3Smrg# include <assert.h> /* note : can still be disabled with NDEBUG */ 4887ec681f3Smrg# define XXH_ASSERT(c) assert(c) 4897ec681f3Smrg#else 4907ec681f3Smrg# define XXH_ASSERT(c) ((void)0) 4917ec681f3Smrg#endif 4927ec681f3Smrg 4937ec681f3Smrg/* note : use after variable declarations */ 4947ec681f3Smrg#define XXH_STATIC_ASSERT(c) { enum { XXH_sa = 1/(int)(!!(c)) }; } 4957ec681f3Smrg 4967ec681f3Smrg 4977ec681f3Smrg/* ************************************* 4987ec681f3Smrg* Basic Types 4997ec681f3Smrg***************************************/ 5007ec681f3Smrg#if !defined (__VMS) \ 5017ec681f3Smrg && (defined (__cplusplus) \ 5027ec681f3Smrg || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) 5037ec681f3Smrg# include <stdint.h> 5047ec681f3Smrg typedef uint8_t xxh_u8; 5057ec681f3Smrg#else 5067ec681f3Smrg typedef unsigned char xxh_u8; 5077ec681f3Smrg#endif 5087ec681f3Smrgtypedef XXH32_hash_t xxh_u32; 5097ec681f3Smrg 5107ec681f3Smrg 5117ec681f3Smrg/* *** Memory access *** */ 5127ec681f3Smrg 5137ec681f3Smrg#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) 5147ec681f3Smrg 5157ec681f3Smrg/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ 5167ec681f3Smrgstatic xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; } 5177ec681f3Smrg 5187ec681f3Smrg#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) 5197ec681f3Smrg 5207ec681f3Smrg/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ 5217ec681f3Smrg/* currently only defined for gcc and icc */ 5227ec681f3Smrgtypedef union { xxh_u32 u32; } __attribute__((packed)) unalign; 5237ec681f3Smrgstatic xxh_u32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } 5247ec681f3Smrg 5257ec681f3Smrg#else 5267ec681f3Smrg 5277ec681f3Smrg/* portable and safe solution. Generally efficient. 5287ec681f3Smrg * see : http://stackoverflow.com/a/32095106/646947 5297ec681f3Smrg */ 5307ec681f3Smrgstatic xxh_u32 XXH_read32(const void* memPtr) 5317ec681f3Smrg{ 5327ec681f3Smrg xxh_u32 val; 5337ec681f3Smrg memcpy(&val, memPtr, sizeof(val)); 5347ec681f3Smrg return val; 5357ec681f3Smrg} 5367ec681f3Smrg 5377ec681f3Smrg#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ 5387ec681f3Smrg 5397ec681f3Smrg 5407ec681f3Smrg/* *** Endianess *** */ 5417ec681f3Smrgtypedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; 5427ec681f3Smrg 5437ec681f3Smrg/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ 5447ec681f3Smrg#ifndef XXH_CPU_LITTLE_ENDIAN 5457ec681f3Smrg# if defined(_WIN32) /* Windows is always little endian */ \ 5467ec681f3Smrg || defined(__LITTLE_ENDIAN__) \ 5477ec681f3Smrg || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) 5487ec681f3Smrg# define XXH_CPU_LITTLE_ENDIAN 1 5497ec681f3Smrg# elif defined(__BIG_ENDIAN__) \ 5507ec681f3Smrg || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) 5517ec681f3Smrg# define XXH_CPU_LITTLE_ENDIAN 0 5527ec681f3Smrg# else 5537ec681f3Smrgstatic int XXH_isLittleEndian(void) 5547ec681f3Smrg{ 5557ec681f3Smrg const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 }; /* don't use static : performance detrimental */ 5567ec681f3Smrg return one.c[0]; 5577ec681f3Smrg} 5587ec681f3Smrg# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian() 5597ec681f3Smrg# endif 5607ec681f3Smrg#endif 5617ec681f3Smrg 5627ec681f3Smrg 5637ec681f3Smrg 5647ec681f3Smrg 5657ec681f3Smrg/* **************************************** 5667ec681f3Smrg* Compiler-specific Functions and Macros 5677ec681f3Smrg******************************************/ 5687ec681f3Smrg#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 5697ec681f3Smrg 5707ec681f3Smrg#ifndef __has_builtin 5717ec681f3Smrg# define __has_builtin(x) 0 5727ec681f3Smrg#endif 5737ec681f3Smrg 5747ec681f3Smrg#if !defined(NO_CLANG_BUILTIN) && __has_builtin(__builtin_rotateleft32) && __has_builtin(__builtin_rotateleft64) 5757ec681f3Smrg# define XXH_rotl32 __builtin_rotateleft32 5767ec681f3Smrg# define XXH_rotl64 __builtin_rotateleft64 5777ec681f3Smrg/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ 5787ec681f3Smrg#elif defined(_MSC_VER) 5797ec681f3Smrg# define XXH_rotl32(x,r) _rotl(x,r) 5807ec681f3Smrg# define XXH_rotl64(x,r) _rotl64(x,r) 5817ec681f3Smrg#else 5827ec681f3Smrg# define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) 5837ec681f3Smrg# define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r)))) 5847ec681f3Smrg#endif 5857ec681f3Smrg 5867ec681f3Smrg#if defined(_MSC_VER) /* Visual Studio */ 5877ec681f3Smrg# define XXH_swap32 _byteswap_ulong 5887ec681f3Smrg#elif XXH_GCC_VERSION >= 403 5897ec681f3Smrg# define XXH_swap32 __builtin_bswap32 5907ec681f3Smrg#else 5917ec681f3Smrgstatic xxh_u32 XXH_swap32 (xxh_u32 x) 5927ec681f3Smrg{ 5937ec681f3Smrg return ((x << 24) & 0xff000000 ) | 5947ec681f3Smrg ((x << 8) & 0x00ff0000 ) | 5957ec681f3Smrg ((x >> 8) & 0x0000ff00 ) | 5967ec681f3Smrg ((x >> 24) & 0x000000ff ); 5977ec681f3Smrg} 5987ec681f3Smrg#endif 5997ec681f3Smrg 6007ec681f3Smrg 6017ec681f3Smrg/* *************************** 6027ec681f3Smrg* Memory reads 6037ec681f3Smrg*****************************/ 6047ec681f3Smrgtypedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; 6057ec681f3Smrg 6067ec681f3SmrgXXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr) 6077ec681f3Smrg{ 6087ec681f3Smrg return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); 6097ec681f3Smrg} 6107ec681f3Smrg 6117ec681f3Smrgstatic xxh_u32 XXH_readBE32(const void* ptr) 6127ec681f3Smrg{ 6137ec681f3Smrg return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); 6147ec681f3Smrg} 6157ec681f3Smrg 6167ec681f3SmrgXXH_FORCE_INLINE xxh_u32 6177ec681f3SmrgXXH_readLE32_align(const void* ptr, XXH_alignment align) 6187ec681f3Smrg{ 6197ec681f3Smrg if (align==XXH_unaligned) { 6207ec681f3Smrg return XXH_readLE32(ptr); 6217ec681f3Smrg } else { 6227ec681f3Smrg return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr); 6237ec681f3Smrg } 6247ec681f3Smrg} 6257ec681f3Smrg 6267ec681f3Smrg 6277ec681f3Smrg/* ************************************* 6287ec681f3Smrg* Misc 6297ec681f3Smrg***************************************/ 6307ec681f3SmrgXXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } 6317ec681f3Smrg 6327ec681f3Smrg 6337ec681f3Smrg/* ******************************************************************* 6347ec681f3Smrg* 32-bit hash functions 6357ec681f3Smrg*********************************************************************/ 6367ec681f3Smrgstatic const xxh_u32 PRIME32_1 = 0x9E3779B1U; /* 0b10011110001101110111100110110001 */ 6377ec681f3Smrgstatic const xxh_u32 PRIME32_2 = 0x85EBCA77U; /* 0b10000101111010111100101001110111 */ 6387ec681f3Smrgstatic const xxh_u32 PRIME32_3 = 0xC2B2AE3DU; /* 0b11000010101100101010111000111101 */ 6397ec681f3Smrgstatic const xxh_u32 PRIME32_4 = 0x27D4EB2FU; /* 0b00100111110101001110101100101111 */ 6407ec681f3Smrgstatic const xxh_u32 PRIME32_5 = 0x165667B1U; /* 0b00010110010101100110011110110001 */ 6417ec681f3Smrg 6427ec681f3Smrgstatic xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) 6437ec681f3Smrg{ 6447ec681f3Smrg acc += input * PRIME32_2; 6457ec681f3Smrg acc = XXH_rotl32(acc, 13); 6467ec681f3Smrg acc *= PRIME32_1; 6477ec681f3Smrg#if defined(__GNUC__) && defined(__SSE4_1__) && !defined(XXH_ENABLE_AUTOVECTORIZE) 6487ec681f3Smrg /* UGLY HACK: 6497ec681f3Smrg * This inline assembly hack forces acc into a normal register. This is the 6507ec681f3Smrg * only thing that prevents GCC and Clang from autovectorizing the XXH32 loop 6517ec681f3Smrg * (pragmas and attributes don't work for some resason) without globally 6527ec681f3Smrg * disabling SSE4.1. 6537ec681f3Smrg * 6547ec681f3Smrg * The reason we want to avoid vectorization is because despite working on 6557ec681f3Smrg * 4 integers at a time, there are multiple factors slowing XXH32 down on 6567ec681f3Smrg * SSE4: 6577ec681f3Smrg * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on newer chips!) 6587ec681f3Smrg * making it slightly slower to multiply four integers at once compared to four 6597ec681f3Smrg * integers independently. Even when pmulld was fastest, Sandy/Ivy Bridge, it is 6607ec681f3Smrg * still not worth it to go into SSE just to multiply unless doing a long operation. 6617ec681f3Smrg * 6627ec681f3Smrg * - Four instructions are required to rotate, 6637ec681f3Smrg * movqda tmp, v // not required with VEX encoding 6647ec681f3Smrg * pslld tmp, 13 // tmp <<= 13 6657ec681f3Smrg * psrld v, 19 // x >>= 19 6667ec681f3Smrg * por v, tmp // x |= tmp 6677ec681f3Smrg * compared to one for scalar: 6687ec681f3Smrg * roll v, 13 // reliably fast across the board 6697ec681f3Smrg * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason 6707ec681f3Smrg * 6717ec681f3Smrg * - Instruction level parallelism is actually more beneficial here because the 6727ec681f3Smrg * SIMD actually serializes this operation: While v1 is rotating, v2 can load data, 6737ec681f3Smrg * while v3 can multiply. SSE forces them to operate together. 6747ec681f3Smrg * 6757ec681f3Smrg * How this hack works: 6767ec681f3Smrg * __asm__("" // Declare an assembly block but don't declare any instructions 6777ec681f3Smrg * : // However, as an Input/Output Operand, 6787ec681f3Smrg * "+r" // constrain a read/write operand (+) as a general purpose register (r). 6797ec681f3Smrg * (acc) // and set acc as the operand 6807ec681f3Smrg * ); 6817ec681f3Smrg * 6827ec681f3Smrg * Because of the 'r', the compiler has promised that seed will be in a 6837ec681f3Smrg * general purpose register and the '+' says that it will be 'read/write', 6847ec681f3Smrg * so it has to assume it has changed. It is like volatile without all the 6857ec681f3Smrg * loads and stores. 6867ec681f3Smrg * 6877ec681f3Smrg * Since the argument has to be in a normal register (not an SSE register), 6887ec681f3Smrg * each time XXH32_round is called, it is impossible to vectorize. */ 6897ec681f3Smrg __asm__("" : "+r" (acc)); 6907ec681f3Smrg#endif 6917ec681f3Smrg return acc; 6927ec681f3Smrg} 6937ec681f3Smrg 6947ec681f3Smrg/* mix all bits */ 6957ec681f3Smrgstatic xxh_u32 XXH32_avalanche(xxh_u32 h32) 6967ec681f3Smrg{ 6977ec681f3Smrg h32 ^= h32 >> 15; 6987ec681f3Smrg h32 *= PRIME32_2; 6997ec681f3Smrg h32 ^= h32 >> 13; 7007ec681f3Smrg h32 *= PRIME32_3; 7017ec681f3Smrg h32 ^= h32 >> 16; 7027ec681f3Smrg return(h32); 7037ec681f3Smrg} 7047ec681f3Smrg 7057ec681f3Smrg#define XXH_get32bits(p) XXH_readLE32_align(p, align) 7067ec681f3Smrg 7077ec681f3Smrgstatic xxh_u32 7087ec681f3SmrgXXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) 7097ec681f3Smrg{ 7107ec681f3Smrg#define PROCESS1 \ 7117ec681f3Smrg h32 += (*ptr++) * PRIME32_5; \ 7127ec681f3Smrg h32 = XXH_rotl32(h32, 11) * PRIME32_1 ; 7137ec681f3Smrg 7147ec681f3Smrg#define PROCESS4 \ 7157ec681f3Smrg h32 += XXH_get32bits(ptr) * PRIME32_3; \ 7167ec681f3Smrg ptr+=4; \ 7177ec681f3Smrg h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; 7187ec681f3Smrg 7197ec681f3Smrg /* Compact rerolled version */ 7207ec681f3Smrg if (XXH_REROLL) { 7217ec681f3Smrg len &= 15; 7227ec681f3Smrg while (len >= 4) { 7237ec681f3Smrg PROCESS4; 7247ec681f3Smrg len -= 4; 7257ec681f3Smrg } 7267ec681f3Smrg while (len > 0) { 7277ec681f3Smrg PROCESS1; 7287ec681f3Smrg --len; 7297ec681f3Smrg } 7307ec681f3Smrg return XXH32_avalanche(h32); 7317ec681f3Smrg } else { 7327ec681f3Smrg switch(len&15) /* or switch(bEnd - p) */ { 7337ec681f3Smrg case 12: PROCESS4; 7347ec681f3Smrg FALLTHROUGH; 7357ec681f3Smrg case 8: PROCESS4; 7367ec681f3Smrg FALLTHROUGH; 7377ec681f3Smrg case 4: PROCESS4; 7387ec681f3Smrg return XXH32_avalanche(h32); 7397ec681f3Smrg 7407ec681f3Smrg case 13: PROCESS4; 7417ec681f3Smrg FALLTHROUGH; 7427ec681f3Smrg case 9: PROCESS4; 7437ec681f3Smrg FALLTHROUGH; 7447ec681f3Smrg case 5: PROCESS4; 7457ec681f3Smrg PROCESS1; 7467ec681f3Smrg return XXH32_avalanche(h32); 7477ec681f3Smrg 7487ec681f3Smrg case 14: PROCESS4; 7497ec681f3Smrg FALLTHROUGH; 7507ec681f3Smrg case 10: PROCESS4; 7517ec681f3Smrg FALLTHROUGH; 7527ec681f3Smrg case 6: PROCESS4; 7537ec681f3Smrg PROCESS1; 7547ec681f3Smrg PROCESS1; 7557ec681f3Smrg return XXH32_avalanche(h32); 7567ec681f3Smrg 7577ec681f3Smrg case 15: PROCESS4; 7587ec681f3Smrg FALLTHROUGH; 7597ec681f3Smrg case 11: PROCESS4; 7607ec681f3Smrg FALLTHROUGH; 7617ec681f3Smrg case 7: PROCESS4; 7627ec681f3Smrg FALLTHROUGH; 7637ec681f3Smrg case 3: PROCESS1; 7647ec681f3Smrg FALLTHROUGH; 7657ec681f3Smrg case 2: PROCESS1; 7667ec681f3Smrg FALLTHROUGH; 7677ec681f3Smrg case 1: PROCESS1; 7687ec681f3Smrg FALLTHROUGH; 7697ec681f3Smrg case 0: return XXH32_avalanche(h32); 7707ec681f3Smrg } 7717ec681f3Smrg XXH_ASSERT(0); 7727ec681f3Smrg return h32; /* reaching this point is deemed impossible */ 7737ec681f3Smrg } 7747ec681f3Smrg} 7757ec681f3Smrg 7767ec681f3SmrgXXH_FORCE_INLINE xxh_u32 7777ec681f3SmrgXXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align) 7787ec681f3Smrg{ 7797ec681f3Smrg const xxh_u8* bEnd = input + len; 7807ec681f3Smrg xxh_u32 h32; 7817ec681f3Smrg 7827ec681f3Smrg#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) 7837ec681f3Smrg if (input==NULL) { 7847ec681f3Smrg len=0; 7857ec681f3Smrg bEnd=input=(const xxh_u8*)(size_t)16; 7867ec681f3Smrg } 7877ec681f3Smrg#endif 7887ec681f3Smrg 7897ec681f3Smrg if (len>=16) { 7907ec681f3Smrg const xxh_u8* const limit = bEnd - 15; 7917ec681f3Smrg xxh_u32 v1 = seed + PRIME32_1 + PRIME32_2; 7927ec681f3Smrg xxh_u32 v2 = seed + PRIME32_2; 7937ec681f3Smrg xxh_u32 v3 = seed + 0; 7947ec681f3Smrg xxh_u32 v4 = seed - PRIME32_1; 7957ec681f3Smrg 7967ec681f3Smrg do { 7977ec681f3Smrg v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; 7987ec681f3Smrg v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4; 7997ec681f3Smrg v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4; 8007ec681f3Smrg v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4; 8017ec681f3Smrg } while (input < limit); 8027ec681f3Smrg 8037ec681f3Smrg h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) 8047ec681f3Smrg + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); 8057ec681f3Smrg } else { 8067ec681f3Smrg h32 = seed + PRIME32_5; 8077ec681f3Smrg } 8087ec681f3Smrg 8097ec681f3Smrg h32 += (xxh_u32)len; 8107ec681f3Smrg 8117ec681f3Smrg return XXH32_finalize(h32, input, len&15, align); 8127ec681f3Smrg} 8137ec681f3Smrg 8147ec681f3Smrg 8157ec681f3SmrgXXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed) 8167ec681f3Smrg{ 8177ec681f3Smrg#if 0 8187ec681f3Smrg /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ 8197ec681f3Smrg XXH32_state_t state; 8207ec681f3Smrg XXH32_reset(&state, seed); 8217ec681f3Smrg XXH32_update(&state, (const xxh_u8*)input, len); 8227ec681f3Smrg return XXH32_digest(&state); 8237ec681f3Smrg 8247ec681f3Smrg#else 8257ec681f3Smrg 8267ec681f3Smrg if (XXH_FORCE_ALIGN_CHECK) { 8277ec681f3Smrg if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ 8287ec681f3Smrg return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned); 8297ec681f3Smrg } } 8307ec681f3Smrg 8317ec681f3Smrg return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned); 8327ec681f3Smrg#endif 8337ec681f3Smrg} 8347ec681f3Smrg 8357ec681f3Smrg 8367ec681f3Smrg 8377ec681f3Smrg/******* Hash streaming *******/ 8387ec681f3Smrg 8397ec681f3SmrgXXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) 8407ec681f3Smrg{ 8417ec681f3Smrg return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); 8427ec681f3Smrg} 8437ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) 8447ec681f3Smrg{ 8457ec681f3Smrg XXH_free(statePtr); 8467ec681f3Smrg return XXH_OK; 8477ec681f3Smrg} 8487ec681f3Smrg 8497ec681f3SmrgXXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) 8507ec681f3Smrg{ 8517ec681f3Smrg memcpy(dstState, srcState, sizeof(*dstState)); 8527ec681f3Smrg} 8537ec681f3Smrg 8547ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed) 8557ec681f3Smrg{ 8567ec681f3Smrg XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ 8577ec681f3Smrg memset(&state, 0, sizeof(state)); 8587ec681f3Smrg state.v1 = seed + PRIME32_1 + PRIME32_2; 8597ec681f3Smrg state.v2 = seed + PRIME32_2; 8607ec681f3Smrg state.v3 = seed + 0; 8617ec681f3Smrg state.v4 = seed - PRIME32_1; 8627ec681f3Smrg /* do not write into reserved, planned to be removed in a future version */ 8637ec681f3Smrg memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); 8647ec681f3Smrg return XXH_OK; 8657ec681f3Smrg} 8667ec681f3Smrg 8677ec681f3Smrg 8687ec681f3SmrgXXH_PUBLIC_API XXH_errorcode 8697ec681f3SmrgXXH32_update(XXH32_state_t* state, const void* input, size_t len) 8707ec681f3Smrg{ 8717ec681f3Smrg if (input==NULL) 8727ec681f3Smrg#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) 8737ec681f3Smrg return XXH_OK; 8747ec681f3Smrg#else 8757ec681f3Smrg return XXH_ERROR; 8767ec681f3Smrg#endif 8777ec681f3Smrg 8787ec681f3Smrg { const xxh_u8* p = (const xxh_u8*)input; 8797ec681f3Smrg const xxh_u8* const bEnd = p + len; 8807ec681f3Smrg 8817ec681f3Smrg state->total_len_32 += (XXH32_hash_t)len; 8827ec681f3Smrg state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); 8837ec681f3Smrg 8847ec681f3Smrg if (state->memsize + len < 16) { /* fill in tmp buffer */ 8857ec681f3Smrg XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len); 8867ec681f3Smrg state->memsize += (XXH32_hash_t)len; 8877ec681f3Smrg return XXH_OK; 8887ec681f3Smrg } 8897ec681f3Smrg 8907ec681f3Smrg if (state->memsize) { /* some data left from previous update */ 8917ec681f3Smrg XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize); 8927ec681f3Smrg { const xxh_u32* p32 = state->mem32; 8937ec681f3Smrg state->v1 = XXH32_round(state->v1, XXH_readLE32(p32)); p32++; 8947ec681f3Smrg state->v2 = XXH32_round(state->v2, XXH_readLE32(p32)); p32++; 8957ec681f3Smrg state->v3 = XXH32_round(state->v3, XXH_readLE32(p32)); p32++; 8967ec681f3Smrg state->v4 = XXH32_round(state->v4, XXH_readLE32(p32)); 8977ec681f3Smrg } 8987ec681f3Smrg p += 16-state->memsize; 8997ec681f3Smrg state->memsize = 0; 9007ec681f3Smrg } 9017ec681f3Smrg 9027ec681f3Smrg if (p <= bEnd-16) { 9037ec681f3Smrg const xxh_u8* const limit = bEnd - 16; 9047ec681f3Smrg xxh_u32 v1 = state->v1; 9057ec681f3Smrg xxh_u32 v2 = state->v2; 9067ec681f3Smrg xxh_u32 v3 = state->v3; 9077ec681f3Smrg xxh_u32 v4 = state->v4; 9087ec681f3Smrg 9097ec681f3Smrg do { 9107ec681f3Smrg v1 = XXH32_round(v1, XXH_readLE32(p)); p+=4; 9117ec681f3Smrg v2 = XXH32_round(v2, XXH_readLE32(p)); p+=4; 9127ec681f3Smrg v3 = XXH32_round(v3, XXH_readLE32(p)); p+=4; 9137ec681f3Smrg v4 = XXH32_round(v4, XXH_readLE32(p)); p+=4; 9147ec681f3Smrg } while (p<=limit); 9157ec681f3Smrg 9167ec681f3Smrg state->v1 = v1; 9177ec681f3Smrg state->v2 = v2; 9187ec681f3Smrg state->v3 = v3; 9197ec681f3Smrg state->v4 = v4; 9207ec681f3Smrg } 9217ec681f3Smrg 9227ec681f3Smrg if (p < bEnd) { 9237ec681f3Smrg XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); 9247ec681f3Smrg state->memsize = (unsigned)(bEnd-p); 9257ec681f3Smrg } 9267ec681f3Smrg } 9277ec681f3Smrg 9287ec681f3Smrg return XXH_OK; 9297ec681f3Smrg} 9307ec681f3Smrg 9317ec681f3Smrg 9327ec681f3SmrgXXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* state) 9337ec681f3Smrg{ 9347ec681f3Smrg xxh_u32 h32; 9357ec681f3Smrg 9367ec681f3Smrg if (state->large_len) { 9377ec681f3Smrg h32 = XXH_rotl32(state->v1, 1) 9387ec681f3Smrg + XXH_rotl32(state->v2, 7) 9397ec681f3Smrg + XXH_rotl32(state->v3, 12) 9407ec681f3Smrg + XXH_rotl32(state->v4, 18); 9417ec681f3Smrg } else { 9427ec681f3Smrg h32 = state->v3 /* == seed */ + PRIME32_5; 9437ec681f3Smrg } 9447ec681f3Smrg 9457ec681f3Smrg h32 += state->total_len_32; 9467ec681f3Smrg 9477ec681f3Smrg return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); 9487ec681f3Smrg} 9497ec681f3Smrg 9507ec681f3Smrg 9517ec681f3Smrg/******* Canonical representation *******/ 9527ec681f3Smrg 9537ec681f3Smrg/*! Default XXH result types are basic unsigned 32 and 64 bits. 9547ec681f3Smrg* The canonical representation follows human-readable write convention, aka big-endian (large digits first). 9557ec681f3Smrg* These functions allow transformation of hash result into and from its canonical format. 9567ec681f3Smrg* This way, hash values can be written into a file or buffer, remaining comparable across different systems. 9577ec681f3Smrg*/ 9587ec681f3Smrg 9597ec681f3SmrgXXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) 9607ec681f3Smrg{ 9617ec681f3Smrg XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); 9627ec681f3Smrg if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); 9637ec681f3Smrg memcpy(dst, &hash, sizeof(*dst)); 9647ec681f3Smrg} 9657ec681f3Smrg 9667ec681f3SmrgXXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) 9677ec681f3Smrg{ 9687ec681f3Smrg return XXH_readBE32(src); 9697ec681f3Smrg} 9707ec681f3Smrg 9717ec681f3Smrg 9727ec681f3Smrg#ifndef XXH_NO_LONG_LONG 9737ec681f3Smrg 9747ec681f3Smrg/* ******************************************************************* 9757ec681f3Smrg* 64-bit hash functions 9767ec681f3Smrg*********************************************************************/ 9777ec681f3Smrg 9787ec681f3Smrg/******* Memory access *******/ 9797ec681f3Smrg 9807ec681f3Smrgtypedef XXH64_hash_t xxh_u64; 9817ec681f3Smrg 9827ec681f3Smrg 9837ec681f3Smrg/*! XXH_REROLL_XXH64: 9847ec681f3Smrg * Whether to reroll the XXH64_finalize() loop. 9857ec681f3Smrg * 9867ec681f3Smrg * Just like XXH32, we can unroll the XXH64_finalize() loop. This can be a performance gain 9877ec681f3Smrg * on 64-bit hosts, as only one jump is required. 9887ec681f3Smrg * 9897ec681f3Smrg * However, on 32-bit hosts, because arithmetic needs to be done with two 32-bit registers, 9907ec681f3Smrg * and 64-bit arithmetic needs to be simulated, it isn't beneficial to unroll. The code becomes 9917ec681f3Smrg * ridiculously large (the largest function in the binary on i386!), and rerolling it saves 9927ec681f3Smrg * anywhere from 3kB to 20kB. It is also slightly faster because it fits into cache better 9937ec681f3Smrg * and is more likely to be inlined by the compiler. 9947ec681f3Smrg * 9957ec681f3Smrg * If XXH_REROLL is defined, this is ignored and the loop is always rerolled. */ 9967ec681f3Smrg#ifndef XXH_REROLL_XXH64 9977ec681f3Smrg# if (defined(__ILP32__) || defined(_ILP32)) /* ILP32 is often defined on 32-bit GCC family */ \ 9987ec681f3Smrg || !(defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) /* x86-64 */ \ 9997ec681f3Smrg || defined(_M_ARM64) || defined(__aarch64__) || defined(__arm64__) /* aarch64 */ \ 10007ec681f3Smrg || defined(__PPC64__) || defined(__PPC64LE__) || defined(__ppc64__) || defined(__powerpc64__) /* ppc64 */ \ 10017ec681f3Smrg || defined(__mips64__) || defined(__mips64)) /* mips64 */ \ 10027ec681f3Smrg || (!defined(SIZE_MAX) || SIZE_MAX < ULLONG_MAX) /* check limits */ 10037ec681f3Smrg# define XXH_REROLL_XXH64 1 10047ec681f3Smrg# else 10057ec681f3Smrg# define XXH_REROLL_XXH64 0 10067ec681f3Smrg# endif 10077ec681f3Smrg#endif /* !defined(XXH_REROLL_XXH64) */ 10087ec681f3Smrg 10097ec681f3Smrg#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) 10107ec681f3Smrg 10117ec681f3Smrg/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ 10127ec681f3Smrgstatic xxh_u64 XXH_read64(const void* memPtr) { return *(const xxh_u64*) memPtr; } 10137ec681f3Smrg 10147ec681f3Smrg#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) 10157ec681f3Smrg 10167ec681f3Smrg/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ 10177ec681f3Smrg/* currently only defined for gcc and icc */ 10187ec681f3Smrgtypedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; 10197ec681f3Smrgstatic xxh_u64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; } 10207ec681f3Smrg 10217ec681f3Smrg#else 10227ec681f3Smrg 10237ec681f3Smrg/* portable and safe solution. Generally efficient. 10247ec681f3Smrg * see : http://stackoverflow.com/a/32095106/646947 10257ec681f3Smrg */ 10267ec681f3Smrg 10277ec681f3Smrgstatic xxh_u64 XXH_read64(const void* memPtr) 10287ec681f3Smrg{ 10297ec681f3Smrg xxh_u64 val; 10307ec681f3Smrg memcpy(&val, memPtr, sizeof(val)); 10317ec681f3Smrg return val; 10327ec681f3Smrg} 10337ec681f3Smrg 10347ec681f3Smrg#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ 10357ec681f3Smrg 10367ec681f3Smrg#if defined(_MSC_VER) /* Visual Studio */ 10377ec681f3Smrg# define XXH_swap64 _byteswap_uint64 10387ec681f3Smrg#elif XXH_GCC_VERSION >= 403 10397ec681f3Smrg# define XXH_swap64 __builtin_bswap64 10407ec681f3Smrg#else 10417ec681f3Smrgstatic xxh_u64 XXH_swap64 (xxh_u64 x) 10427ec681f3Smrg{ 10437ec681f3Smrg return ((x << 56) & 0xff00000000000000ULL) | 10447ec681f3Smrg ((x << 40) & 0x00ff000000000000ULL) | 10457ec681f3Smrg ((x << 24) & 0x0000ff0000000000ULL) | 10467ec681f3Smrg ((x << 8) & 0x000000ff00000000ULL) | 10477ec681f3Smrg ((x >> 8) & 0x00000000ff000000ULL) | 10487ec681f3Smrg ((x >> 24) & 0x0000000000ff0000ULL) | 10497ec681f3Smrg ((x >> 40) & 0x000000000000ff00ULL) | 10507ec681f3Smrg ((x >> 56) & 0x00000000000000ffULL); 10517ec681f3Smrg} 10527ec681f3Smrg#endif 10537ec681f3Smrg 10547ec681f3SmrgXXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* ptr) 10557ec681f3Smrg{ 10567ec681f3Smrg return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); 10577ec681f3Smrg} 10587ec681f3Smrg 10597ec681f3Smrgstatic xxh_u64 XXH_readBE64(const void* ptr) 10607ec681f3Smrg{ 10617ec681f3Smrg return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); 10627ec681f3Smrg} 10637ec681f3Smrg 10647ec681f3SmrgXXH_FORCE_INLINE xxh_u64 10657ec681f3SmrgXXH_readLE64_align(const void* ptr, XXH_alignment align) 10667ec681f3Smrg{ 10677ec681f3Smrg if (align==XXH_unaligned) 10687ec681f3Smrg return XXH_readLE64(ptr); 10697ec681f3Smrg else 10707ec681f3Smrg return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr); 10717ec681f3Smrg} 10727ec681f3Smrg 10737ec681f3Smrg 10747ec681f3Smrg/******* xxh64 *******/ 10757ec681f3Smrg 10767ec681f3Smrgstatic const xxh_u64 PRIME64_1 = 0x9E3779B185EBCA87ULL; /* 0b1001111000110111011110011011000110000101111010111100101010000111 */ 10777ec681f3Smrgstatic const xxh_u64 PRIME64_2 = 0xC2B2AE3D27D4EB4FULL; /* 0b1100001010110010101011100011110100100111110101001110101101001111 */ 10787ec681f3Smrgstatic const xxh_u64 PRIME64_3 = 0x165667B19E3779F9ULL; /* 0b0001011001010110011001111011000110011110001101110111100111111001 */ 10797ec681f3Smrgstatic const xxh_u64 PRIME64_4 = 0x85EBCA77C2B2AE63ULL; /* 0b1000010111101011110010100111011111000010101100101010111001100011 */ 10807ec681f3Smrgstatic const xxh_u64 PRIME64_5 = 0x27D4EB2F165667C5ULL; /* 0b0010011111010100111010110010111100010110010101100110011111000101 */ 10817ec681f3Smrg 10827ec681f3Smrgstatic xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) 10837ec681f3Smrg{ 10847ec681f3Smrg acc += input * PRIME64_2; 10857ec681f3Smrg acc = XXH_rotl64(acc, 31); 10867ec681f3Smrg acc *= PRIME64_1; 10877ec681f3Smrg return acc; 10887ec681f3Smrg} 10897ec681f3Smrg 10907ec681f3Smrgstatic xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val) 10917ec681f3Smrg{ 10927ec681f3Smrg val = XXH64_round(0, val); 10937ec681f3Smrg acc ^= val; 10947ec681f3Smrg acc = acc * PRIME64_1 + PRIME64_4; 10957ec681f3Smrg return acc; 10967ec681f3Smrg} 10977ec681f3Smrg 10987ec681f3Smrgstatic xxh_u64 XXH64_avalanche(xxh_u64 h64) 10997ec681f3Smrg{ 11007ec681f3Smrg h64 ^= h64 >> 33; 11017ec681f3Smrg h64 *= PRIME64_2; 11027ec681f3Smrg h64 ^= h64 >> 29; 11037ec681f3Smrg h64 *= PRIME64_3; 11047ec681f3Smrg h64 ^= h64 >> 32; 11057ec681f3Smrg return h64; 11067ec681f3Smrg} 11077ec681f3Smrg 11087ec681f3Smrg 11097ec681f3Smrg#define XXH_get64bits(p) XXH_readLE64_align(p, align) 11107ec681f3Smrg 11117ec681f3Smrgstatic xxh_u64 11127ec681f3SmrgXXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align) 11137ec681f3Smrg{ 11147ec681f3Smrg#define PROCESS1_64 \ 11157ec681f3Smrg h64 ^= (*ptr++) * PRIME64_5; \ 11167ec681f3Smrg h64 = XXH_rotl64(h64, 11) * PRIME64_1; 11177ec681f3Smrg 11187ec681f3Smrg#define PROCESS4_64 \ 11197ec681f3Smrg h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * PRIME64_1; \ 11207ec681f3Smrg ptr+=4; \ 11217ec681f3Smrg h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; 11227ec681f3Smrg 11237ec681f3Smrg#define PROCESS8_64 { \ 11247ec681f3Smrg xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr)); \ 11257ec681f3Smrg ptr+=8; \ 11267ec681f3Smrg h64 ^= k1; \ 11277ec681f3Smrg h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \ 11287ec681f3Smrg} 11297ec681f3Smrg 11307ec681f3Smrg /* Rerolled version for 32-bit targets is faster and much smaller. */ 11317ec681f3Smrg if (XXH_REROLL || XXH_REROLL_XXH64) { 11327ec681f3Smrg len &= 31; 11337ec681f3Smrg while (len >= 8) { 11347ec681f3Smrg PROCESS8_64; 11357ec681f3Smrg len -= 8; 11367ec681f3Smrg } 11377ec681f3Smrg if (len >= 4) { 11387ec681f3Smrg PROCESS4_64; 11397ec681f3Smrg len -= 4; 11407ec681f3Smrg } 11417ec681f3Smrg while (len > 0) { 11427ec681f3Smrg PROCESS1_64; 11437ec681f3Smrg --len; 11447ec681f3Smrg } 11457ec681f3Smrg return XXH64_avalanche(h64); 11467ec681f3Smrg } else { 11477ec681f3Smrg switch(len & 31) { 11487ec681f3Smrg case 24: PROCESS8_64; 11497ec681f3Smrg FALLTHROUGH; 11507ec681f3Smrg case 16: PROCESS8_64; 11517ec681f3Smrg FALLTHROUGH; 11527ec681f3Smrg case 8: PROCESS8_64; 11537ec681f3Smrg return XXH64_avalanche(h64); 11547ec681f3Smrg 11557ec681f3Smrg case 28: PROCESS8_64; 11567ec681f3Smrg FALLTHROUGH; 11577ec681f3Smrg case 20: PROCESS8_64; 11587ec681f3Smrg FALLTHROUGH; 11597ec681f3Smrg case 12: PROCESS8_64; 11607ec681f3Smrg FALLTHROUGH; 11617ec681f3Smrg case 4: PROCESS4_64; 11627ec681f3Smrg return XXH64_avalanche(h64); 11637ec681f3Smrg 11647ec681f3Smrg case 25: PROCESS8_64; 11657ec681f3Smrg FALLTHROUGH; 11667ec681f3Smrg case 17: PROCESS8_64; 11677ec681f3Smrg FALLTHROUGH; 11687ec681f3Smrg case 9: PROCESS8_64; 11697ec681f3Smrg PROCESS1_64; 11707ec681f3Smrg return XXH64_avalanche(h64); 11717ec681f3Smrg 11727ec681f3Smrg case 29: PROCESS8_64; 11737ec681f3Smrg FALLTHROUGH; 11747ec681f3Smrg case 21: PROCESS8_64; 11757ec681f3Smrg FALLTHROUGH; 11767ec681f3Smrg case 13: PROCESS8_64; 11777ec681f3Smrg FALLTHROUGH; 11787ec681f3Smrg case 5: PROCESS4_64; 11797ec681f3Smrg PROCESS1_64; 11807ec681f3Smrg return XXH64_avalanche(h64); 11817ec681f3Smrg 11827ec681f3Smrg case 26: PROCESS8_64; 11837ec681f3Smrg FALLTHROUGH; 11847ec681f3Smrg case 18: PROCESS8_64; 11857ec681f3Smrg FALLTHROUGH; 11867ec681f3Smrg case 10: PROCESS8_64; 11877ec681f3Smrg PROCESS1_64; 11887ec681f3Smrg PROCESS1_64; 11897ec681f3Smrg return XXH64_avalanche(h64); 11907ec681f3Smrg 11917ec681f3Smrg case 30: PROCESS8_64; 11927ec681f3Smrg FALLTHROUGH; 11937ec681f3Smrg case 22: PROCESS8_64; 11947ec681f3Smrg FALLTHROUGH; 11957ec681f3Smrg case 14: PROCESS8_64; 11967ec681f3Smrg FALLTHROUGH; 11977ec681f3Smrg case 6: PROCESS4_64; 11987ec681f3Smrg PROCESS1_64; 11997ec681f3Smrg PROCESS1_64; 12007ec681f3Smrg return XXH64_avalanche(h64); 12017ec681f3Smrg 12027ec681f3Smrg case 27: PROCESS8_64; 12037ec681f3Smrg FALLTHROUGH; 12047ec681f3Smrg case 19: PROCESS8_64; 12057ec681f3Smrg FALLTHROUGH; 12067ec681f3Smrg case 11: PROCESS8_64; 12077ec681f3Smrg PROCESS1_64; 12087ec681f3Smrg PROCESS1_64; 12097ec681f3Smrg PROCESS1_64; 12107ec681f3Smrg return XXH64_avalanche(h64); 12117ec681f3Smrg 12127ec681f3Smrg case 31: PROCESS8_64; 12137ec681f3Smrg FALLTHROUGH; 12147ec681f3Smrg case 23: PROCESS8_64; 12157ec681f3Smrg FALLTHROUGH; 12167ec681f3Smrg case 15: PROCESS8_64; 12177ec681f3Smrg FALLTHROUGH; 12187ec681f3Smrg case 7: PROCESS4_64; 12197ec681f3Smrg FALLTHROUGH; 12207ec681f3Smrg case 3: PROCESS1_64; 12217ec681f3Smrg FALLTHROUGH; 12227ec681f3Smrg case 2: PROCESS1_64; 12237ec681f3Smrg FALLTHROUGH; 12247ec681f3Smrg case 1: PROCESS1_64; 12257ec681f3Smrg FALLTHROUGH; 12267ec681f3Smrg case 0: return XXH64_avalanche(h64); 12277ec681f3Smrg } 12287ec681f3Smrg } 12297ec681f3Smrg /* impossible to reach */ 12307ec681f3Smrg XXH_ASSERT(0); 12317ec681f3Smrg return 0; /* unreachable, but some compilers complain without it */ 12327ec681f3Smrg} 12337ec681f3Smrg 12347ec681f3SmrgXXH_FORCE_INLINE xxh_u64 12357ec681f3SmrgXXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align) 12367ec681f3Smrg{ 12377ec681f3Smrg const xxh_u8* bEnd = input + len; 12387ec681f3Smrg xxh_u64 h64; 12397ec681f3Smrg 12407ec681f3Smrg#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) 12417ec681f3Smrg if (input==NULL) { 12427ec681f3Smrg len=0; 12437ec681f3Smrg bEnd=input=(const xxh_u8*)(size_t)32; 12447ec681f3Smrg } 12457ec681f3Smrg#endif 12467ec681f3Smrg 12477ec681f3Smrg if (len>=32) { 12487ec681f3Smrg const xxh_u8* const limit = bEnd - 32; 12497ec681f3Smrg xxh_u64 v1 = seed + PRIME64_1 + PRIME64_2; 12507ec681f3Smrg xxh_u64 v2 = seed + PRIME64_2; 12517ec681f3Smrg xxh_u64 v3 = seed + 0; 12527ec681f3Smrg xxh_u64 v4 = seed - PRIME64_1; 12537ec681f3Smrg 12547ec681f3Smrg do { 12557ec681f3Smrg v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; 12567ec681f3Smrg v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8; 12577ec681f3Smrg v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8; 12587ec681f3Smrg v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8; 12597ec681f3Smrg } while (input<=limit); 12607ec681f3Smrg 12617ec681f3Smrg h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); 12627ec681f3Smrg h64 = XXH64_mergeRound(h64, v1); 12637ec681f3Smrg h64 = XXH64_mergeRound(h64, v2); 12647ec681f3Smrg h64 = XXH64_mergeRound(h64, v3); 12657ec681f3Smrg h64 = XXH64_mergeRound(h64, v4); 12667ec681f3Smrg 12677ec681f3Smrg } else { 12687ec681f3Smrg h64 = seed + PRIME64_5; 12697ec681f3Smrg } 12707ec681f3Smrg 12717ec681f3Smrg h64 += (xxh_u64) len; 12727ec681f3Smrg 12737ec681f3Smrg return XXH64_finalize(h64, input, len, align); 12747ec681f3Smrg} 12757ec681f3Smrg 12767ec681f3Smrg 12777ec681f3SmrgXXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed) 12787ec681f3Smrg{ 12797ec681f3Smrg#if 0 12807ec681f3Smrg /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ 12817ec681f3Smrg XXH64_state_t state; 12827ec681f3Smrg XXH64_reset(&state, seed); 12837ec681f3Smrg XXH64_update(&state, (const xxh_u8*)input, len); 12847ec681f3Smrg return XXH64_digest(&state); 12857ec681f3Smrg 12867ec681f3Smrg#else 12877ec681f3Smrg 12887ec681f3Smrg if (XXH_FORCE_ALIGN_CHECK) { 12897ec681f3Smrg if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ 12907ec681f3Smrg return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_aligned); 12917ec681f3Smrg } } 12927ec681f3Smrg 12937ec681f3Smrg return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned); 12947ec681f3Smrg 12957ec681f3Smrg#endif 12967ec681f3Smrg} 12977ec681f3Smrg 12987ec681f3Smrg/******* Hash Streaming *******/ 12997ec681f3Smrg 13007ec681f3SmrgXXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) 13017ec681f3Smrg{ 13027ec681f3Smrg return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); 13037ec681f3Smrg} 13047ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) 13057ec681f3Smrg{ 13067ec681f3Smrg XXH_free(statePtr); 13077ec681f3Smrg return XXH_OK; 13087ec681f3Smrg} 13097ec681f3Smrg 13107ec681f3SmrgXXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState) 13117ec681f3Smrg{ 13127ec681f3Smrg memcpy(dstState, srcState, sizeof(*dstState)); 13137ec681f3Smrg} 13147ec681f3Smrg 13157ec681f3SmrgXXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed) 13167ec681f3Smrg{ 13177ec681f3Smrg XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ 13187ec681f3Smrg memset(&state, 0, sizeof(state)); 13197ec681f3Smrg state.v1 = seed + PRIME64_1 + PRIME64_2; 13207ec681f3Smrg state.v2 = seed + PRIME64_2; 13217ec681f3Smrg state.v3 = seed + 0; 13227ec681f3Smrg state.v4 = seed - PRIME64_1; 13237ec681f3Smrg /* do not write into reserved64, might be removed in a future version */ 13247ec681f3Smrg memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved64)); 13257ec681f3Smrg return XXH_OK; 13267ec681f3Smrg} 13277ec681f3Smrg 13287ec681f3SmrgXXH_PUBLIC_API XXH_errorcode 13297ec681f3SmrgXXH64_update (XXH64_state_t* state, const void* input, size_t len) 13307ec681f3Smrg{ 13317ec681f3Smrg if (input==NULL) 13327ec681f3Smrg#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) 13337ec681f3Smrg return XXH_OK; 13347ec681f3Smrg#else 13357ec681f3Smrg return XXH_ERROR; 13367ec681f3Smrg#endif 13377ec681f3Smrg 13387ec681f3Smrg { const xxh_u8* p = (const xxh_u8*)input; 13397ec681f3Smrg const xxh_u8* const bEnd = p + len; 13407ec681f3Smrg 13417ec681f3Smrg state->total_len += len; 13427ec681f3Smrg 13437ec681f3Smrg if (state->memsize + len < 32) { /* fill in tmp buffer */ 13447ec681f3Smrg XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len); 13457ec681f3Smrg state->memsize += (xxh_u32)len; 13467ec681f3Smrg return XXH_OK; 13477ec681f3Smrg } 13487ec681f3Smrg 13497ec681f3Smrg if (state->memsize) { /* tmp buffer is full */ 13507ec681f3Smrg XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize); 13517ec681f3Smrg state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0)); 13527ec681f3Smrg state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1)); 13537ec681f3Smrg state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2)); 13547ec681f3Smrg state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3)); 13557ec681f3Smrg p += 32-state->memsize; 13567ec681f3Smrg state->memsize = 0; 13577ec681f3Smrg } 13587ec681f3Smrg 13597ec681f3Smrg if (p+32 <= bEnd) { 13607ec681f3Smrg const xxh_u8* const limit = bEnd - 32; 13617ec681f3Smrg xxh_u64 v1 = state->v1; 13627ec681f3Smrg xxh_u64 v2 = state->v2; 13637ec681f3Smrg xxh_u64 v3 = state->v3; 13647ec681f3Smrg xxh_u64 v4 = state->v4; 13657ec681f3Smrg 13667ec681f3Smrg do { 13677ec681f3Smrg v1 = XXH64_round(v1, XXH_readLE64(p)); p+=8; 13687ec681f3Smrg v2 = XXH64_round(v2, XXH_readLE64(p)); p+=8; 13697ec681f3Smrg v3 = XXH64_round(v3, XXH_readLE64(p)); p+=8; 13707ec681f3Smrg v4 = XXH64_round(v4, XXH_readLE64(p)); p+=8; 13717ec681f3Smrg } while (p<=limit); 13727ec681f3Smrg 13737ec681f3Smrg state->v1 = v1; 13747ec681f3Smrg state->v2 = v2; 13757ec681f3Smrg state->v3 = v3; 13767ec681f3Smrg state->v4 = v4; 13777ec681f3Smrg } 13787ec681f3Smrg 13797ec681f3Smrg if (p < bEnd) { 13807ec681f3Smrg XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); 13817ec681f3Smrg state->memsize = (unsigned)(bEnd-p); 13827ec681f3Smrg } 13837ec681f3Smrg } 13847ec681f3Smrg 13857ec681f3Smrg return XXH_OK; 13867ec681f3Smrg} 13877ec681f3Smrg 13887ec681f3Smrg 13897ec681f3SmrgXXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* state) 13907ec681f3Smrg{ 13917ec681f3Smrg xxh_u64 h64; 13927ec681f3Smrg 13937ec681f3Smrg if (state->total_len >= 32) { 13947ec681f3Smrg xxh_u64 const v1 = state->v1; 13957ec681f3Smrg xxh_u64 const v2 = state->v2; 13967ec681f3Smrg xxh_u64 const v3 = state->v3; 13977ec681f3Smrg xxh_u64 const v4 = state->v4; 13987ec681f3Smrg 13997ec681f3Smrg h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); 14007ec681f3Smrg h64 = XXH64_mergeRound(h64, v1); 14017ec681f3Smrg h64 = XXH64_mergeRound(h64, v2); 14027ec681f3Smrg h64 = XXH64_mergeRound(h64, v3); 14037ec681f3Smrg h64 = XXH64_mergeRound(h64, v4); 14047ec681f3Smrg } else { 14057ec681f3Smrg h64 = state->v3 /*seed*/ + PRIME64_5; 14067ec681f3Smrg } 14077ec681f3Smrg 14087ec681f3Smrg h64 += (xxh_u64) state->total_len; 14097ec681f3Smrg 14107ec681f3Smrg return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); 14117ec681f3Smrg} 14127ec681f3Smrg 14137ec681f3Smrg 14147ec681f3Smrg/******* Canonical representation *******/ 14157ec681f3Smrg 14167ec681f3SmrgXXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) 14177ec681f3Smrg{ 14187ec681f3Smrg XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); 14197ec681f3Smrg if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); 14207ec681f3Smrg memcpy(dst, &hash, sizeof(*dst)); 14217ec681f3Smrg} 14227ec681f3Smrg 14237ec681f3SmrgXXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) 14247ec681f3Smrg{ 14257ec681f3Smrg return XXH_readBE64(src); 14267ec681f3Smrg} 14277ec681f3Smrg 14287ec681f3Smrg 14297ec681f3Smrg 14307ec681f3Smrg/* ********************************************************************* 14317ec681f3Smrg* XXH3 14327ec681f3Smrg* New generation hash designed for speed on small keys and vectorization 14337ec681f3Smrg************************************************************************ */ 14347ec681f3Smrg 14357ec681f3Smrg/* #include "xxh3.h" */ 14367ec681f3Smrg 14377ec681f3Smrg 14387ec681f3Smrg#endif /* XXH_NO_LONG_LONG */ 14397ec681f3Smrg 14407ec681f3Smrg 14417ec681f3Smrg#endif /* XXH_IMPLEMENTATION */ 14427ec681f3Smrg 14437ec681f3Smrg 14447ec681f3Smrg#if defined (__cplusplus) 14457ec681f3Smrg} 14467ec681f3Smrg#endif 1447