1/*2 * xxHash - Extremely Fast Hash algorithm3 * Header File4 * Copyright (C) 2012-2020 Yann Collet5 *6 * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)7 *8 * Redistribution and use in source and binary forms, with or without9 * modification, are permitted provided that the following conditions are10 * met:11 *12 * * Redistributions of source code must retain the above copyright13 * notice, this list of conditions and the following disclaimer.14 * * Redistributions in binary form must reproduce the above15 * copyright notice, this list of conditions and the following disclaimer16 * in the documentation and/or other materials provided with the17 * distribution.18 *19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.30 *31 * You can contact the author at:32 * - xxHash homepage: https://www.xxhash.com33 * - xxHash source repository: https://github.com/Cyan4973/xxHash34 */35/*!36 * @mainpage xxHash37 *38 * @file xxhash.h39 * xxHash prototypes and implementation40 */41/* TODO: update */42/* Notice extracted from xxHash homepage:4344xxHash is an extremely fast hash algorithm, running at RAM speed limits.45It also successfully passes all tests from the SMHasher suite.4647Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)4849Name Speed Q.Score Author50xxHash 5.4 GB/s 1051CrapWow 3.2 GB/s 2 Andrew52MurmurHash 3a 2.7 GB/s 10 Austin Appleby53SpookyHash 2.0 GB/s 10 Bob Jenkins54SBox 1.4 GB/s 9 Bret Mulvey55Lookup3 1.2 GB/s 9 Bob Jenkins56SuperFastHash 1.2 GB/s 1 Paul Hsieh57CityHash64 1.05 GB/s 10 Pike & Alakuijala58FNV 0.55 GB/s 5 Fowler, Noll, Vo59CRC32 0.43 GB/s 960MD5-32 0.33 GB/s 10 Ronald L. Rivest61SHA1-32 0.28 GB/s 106263Q.Score is a measure of quality of the hash function.64It depends on successfully passing SMHasher test set.6510 is a perfect score.6667Note: SMHasher's CRC32 implementation is not the fastest one.68Other speed-oriented implementations can be faster,69especially in combination with PCLMUL instruction:70https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c34900923404611707357172A 64-bit version, named XXH64, is available since r35.73It offers much better speed, but for 64-bit applications only.74Name Speed on 64 bits Speed on 32 bits75XXH64 13.8 GB/s 1.9 GB/s76XXH32 6.8 GB/s 6.0 GB/s77*/7879#if defined (__cplusplus)80extern "C" {81#endif8283/* ****************************84 * INLINE mode85 ******************************/86/*!87 * XXH_INLINE_ALL (and XXH_PRIVATE_API)88 * Use these build macros to inline xxhash into the target unit.89 * Inlining improves performance on small inputs, especially when the length is90 * expressed as a compile-time constant:91 *92 * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html93 *94 * It also keeps xxHash symbols private to the unit, so they are not exported.95 *96 * Usage:97 * #define XXH_INLINE_ALL98 * #include "xxhash.h"99 *100 * Do not compile and link xxhash.o as a separate object, as it is not useful.101 */102#if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \103 && !defined(XXH_INLINE_ALL_31684351384)104 /* this section should be traversed only once */105# define XXH_INLINE_ALL_31684351384106 /* give access to the advanced API, required to compile implementations */107# undef XXH_STATIC_LINKING_ONLY /* avoid macro redef */108# define XXH_STATIC_LINKING_ONLY109 /* make all functions private */110# undef XXH_PUBLIC_API111# if defined(__GNUC__)112# define XXH_PUBLIC_API static __inline __attribute__((unused))113# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)114# define XXH_PUBLIC_API static inline115# elif defined(_MSC_VER)116# define XXH_PUBLIC_API static __inline117# else118 /* note: this version may generate warnings for unused static functions */119# define XXH_PUBLIC_API static120# endif121122 /*123 * This part deals with the special case where a unit wants to inline xxHash,124 * but "xxhash.h" has previously been included without XXH_INLINE_ALL, such125 * as part of some previously included *.h header file.126 * Without further action, the new include would just be ignored,127 * and functions would effectively _not_ be inlined (silent failure).128 * The following macros solve this situation by prefixing all inlined names,129 * avoiding naming collision with previous inclusions.130 */131# ifdef XXH_NAMESPACE132# error "XXH_INLINE_ALL with XXH_NAMESPACE is not supported"133 /*134 * Note: Alternative: #undef all symbols (it's a pretty large list).135 * Without #error: it compiles, but functions are actually not inlined.136 */137# endif138# define XXH_NAMESPACE XXH_INLINE_139 /*140 * Some identifiers (enums, type names) are not symbols, but they must141 * still be renamed to avoid redeclaration.142 * Alternative solution: do not redeclare them.143 * However, this requires some #ifdefs, and is a more dispersed action.144 * Meanwhile, renaming can be achieved in a single block145 */146# define XXH_IPREF(Id) XXH_INLINE_ ## Id147# define XXH_OK XXH_IPREF(XXH_OK)148# define XXH_ERROR XXH_IPREF(XXH_ERROR)149# define XXH_errorcode XXH_IPREF(XXH_errorcode)150# define XXH32_canonical_t XXH_IPREF(XXH32_canonical_t)151# define XXH64_canonical_t XXH_IPREF(XXH64_canonical_t)152# define XXH128_canonical_t XXH_IPREF(XXH128_canonical_t)153# define XXH32_state_s XXH_IPREF(XXH32_state_s)154# define XXH32_state_t XXH_IPREF(XXH32_state_t)155# define XXH64_state_s XXH_IPREF(XXH64_state_s)156# define XXH64_state_t XXH_IPREF(XXH64_state_t)157# define XXH3_state_s XXH_IPREF(XXH3_state_s)158# define XXH3_state_t XXH_IPREF(XXH3_state_t)159# define XXH128_hash_t XXH_IPREF(XXH128_hash_t)160 /* Ensure the header is parsed again, even if it was previously included */161# undef XXHASH_H_5627135585666179162# undef XXHASH_H_STATIC_13879238742163#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */164165166167/* ****************************************************************168 * Stable API169 *****************************************************************/170#ifndef XXHASH_H_5627135585666179171#define XXHASH_H_5627135585666179 1172173174/*!175 * @defgroup public Public API176 * Contains details on the public xxHash functions.177 * @{178 */179/* specific declaration modes for Windows */180#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)181# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))182# ifdef XXH_EXPORT183# define XXH_PUBLIC_API __declspec(dllexport)184# elif XXH_IMPORT185# define XXH_PUBLIC_API __declspec(dllimport)186# endif187# else188# define XXH_PUBLIC_API /* do nothing */189# endif190#endif191192#ifdef XXH_DOXYGEN193/*!194 * @brief Emulate a namespace by transparently prefixing all symbols.195 *196 * If you want to include _and expose_ xxHash functions from within your own197 * library, but also want to avoid symbol collisions with other libraries which198 * may also include xxHash, you can use XXH_NAMESPACE to automatically prefix199 * any public symbol from xxhash library with the value of XXH_NAMESPACE200 * (therefore, avoid empty or numeric values).201 *202 * Note that no change is required within the calling program as long as it203 * includes `xxhash.h`: Regular symbol names will be automatically translated204 * by this header.205 */206# define XXH_NAMESPACE /* YOUR NAME HERE */207# undef XXH_NAMESPACE208#endif209210#ifdef XXH_NAMESPACE211# define XXH_CAT(A,B) A##B212# define XXH_NAME2(A,B) XXH_CAT(A,B)213# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)214/* XXH32 */215# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)216# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)217# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)218# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)219# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)220# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)221# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)222# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)223# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)224/* XXH64 */225# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)226# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)227# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)228# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)229# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)230# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)231# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)232# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)233# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)234/* XXH3_64bits */235# define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits)236# define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret)237# define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed)238# define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState)239# define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState)240# define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState)241# define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset)242# define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed)243# define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret)244# define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update)245# define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest)246# define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret)247/* XXH3_128bits */248# define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128)249# define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits)250# define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed)251# define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret)252# define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset)253# define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed)254# define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret)255# define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update)256# define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest)257# define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual)258# define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp)259# define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash)260# define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical)261#endif262263264/* *************************************265* Version266***************************************/267#define XXH_VERSION_MAJOR 0268#define XXH_VERSION_MINOR 8269#define XXH_VERSION_RELEASE 0270#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)271272/*!273 * @brief Obtains the xxHash version.274 *275 * This is only useful when xxHash is compiled as a shared library, as it is276 * independent of the version defined in the header.277 *278 * @return `XXH_VERSION_NUMBER` as of when the function was compiled.279 */280XXH_PUBLIC_API unsigned XXH_versionNumber (void);281282283/* ****************************284* Definitions285******************************/286#include <stddef.h> /* size_t */287typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;288289290/*-**********************************************************************291* 32-bit hash292************************************************************************/293#if defined(XXH_DOXYGEN) /* Don't show <stdint.h> include */294/*!295 * @brief An unsigned 32-bit integer.296 *297 * Not necessarily defined to `uint32_t` but functionally equivalent.298 */299typedef uint32_t XXH32_hash_t;300#elif !defined (__VMS) \301 && (defined (__cplusplus) \302 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )303# include <stdint.h>304 typedef uint32_t XXH32_hash_t;305#else306# include <limits.h>307# if UINT_MAX == 0xFFFFFFFFUL308 typedef unsigned int XXH32_hash_t;309# else310# if ULONG_MAX == 0xFFFFFFFFUL311 typedef unsigned long XXH32_hash_t;312# else313# error "unsupported platform: need a 32-bit type"314# endif315# endif316#endif317318/*!319 * @}320 *321 * @defgroup xxh32_family XXH32 family322 * @ingroup public323 * Contains functions used in the classic 32-bit xxHash algorithm.324 *325 * @note326 * XXH32 is considered rather weak by today's standards.327 * The @ref xxh3_family provides competitive speed for both 32-bit and 64-bit328 * systems, and offers true 64/128 bit hash results. It provides a superior329 * level of dispersion, and greatly reduces the risks of collisions.330 *331 * @see @ref xxh64_family, @ref xxh3_family : Other xxHash families332 * @see @ref xxh32_impl for implementation details333 * @{334 */335336/*!337 * @brief Calculates the 32-bit hash of @p input using xxHash32.338 *339 * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s340 *341 * @param input The block of data to be hashed, at least @p length bytes in size.342 * @param length The length of @p input, in bytes.343 * @param seed The 32-bit seed to alter the hash's output predictably.344 *345 * @pre346 * The memory between @p input and @p input + @p length must be valid,347 * readable, contiguous memory. However, if @p length is `0`, @p input may be348 * `NULL`. In C++, this also must be *TriviallyCopyable*.349 *350 * @return The calculated 32-bit hash value.351 *352 * @see353 * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():354 * Direct equivalents for the other variants of xxHash.355 * @see356 * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version.357 */358XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed);359360/*!361 * Streaming functions generate the xxHash value from an incremental input.362 * This method is slower than single-call functions, due to state management.363 * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized.364 *365 * An XXH state must first be allocated using `XXH*_createState()`.366 *367 * Start a new hash by initializing the state with a seed using `XXH*_reset()`.368 *369 * Then, feed the hash state by calling `XXH*_update()` as many times as necessary.370 *371 * The function returns an error code, with 0 meaning OK, and any other value372 * meaning there is an error.373 *374 * Finally, a hash value can be produced anytime, by using `XXH*_digest()`.375 * This function returns the nn-bits hash as an int or long long.376 *377 * It's still possible to continue inserting input into the hash state after a378 * digest, and generate new hash values later on by invoking `XXH*_digest()`.379 *380 * When done, release the state using `XXH*_freeState()`.381 *382 * Example code for incrementally hashing a file:383 * @code{.c}384 * #include <stdio.h>385 * #include <xxhash.h>386 * #define BUFFER_SIZE 256387 *388 * // Note: XXH64 and XXH3 use the same interface.389 * XXH32_hash_t390 * hashFile(FILE* stream)391 * {392 * XXH32_state_t* state;393 * unsigned char buf[BUFFER_SIZE];394 * size_t amt;395 * XXH32_hash_t hash;396 *397 * state = XXH32_createState(); // Create a state398 * assert(state != NULL); // Error check here399 * XXH32_reset(state, 0xbaad5eed); // Reset state with our seed400 * while ((amt = fread(buf, 1, sizeof(buf), stream)) != 0) {401 * XXH32_update(state, buf, amt); // Hash the file in chunks402 * }403 * hash = XXH32_digest(state); // Finalize the hash404 * XXH32_freeState(state); // Clean up405 * return hash;406 * }407 * @endcode408 */409410/*!411 * @typedef struct XXH32_state_s XXH32_state_t412 * @brief The opaque state struct for the XXH32 streaming API.413 *414 * @see XXH32_state_s for details.415 */416typedef struct XXH32_state_s XXH32_state_t;417418/*!419 * @brief Allocates an @ref XXH32_state_t.420 *421 * Must be freed with XXH32_freeState().422 * @return An allocated XXH32_state_t on success, `NULL` on failure.423 */424XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);425/*!426 * @brief Frees an @ref XXH32_state_t.427 *428 * Must be allocated with XXH32_createState().429 * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState().430 * @return XXH_OK.431 */432XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);433/*!434 * @brief Copies one @ref XXH32_state_t to another.435 *436 * @param dst_state The state to copy to.437 * @param src_state The state to copy from.438 * @pre439 * @p dst_state and @p src_state must not be `NULL` and must not overlap.440 */441XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);442443/*!444 * @brief Resets an @ref XXH32_state_t to begin a new hash.445 *446 * This function resets and seeds a state. Call it before @ref XXH32_update().447 *448 * @param statePtr The state struct to reset.449 * @param seed The 32-bit seed to alter the hash result predictably.450 *451 * @pre452 * @p statePtr must not be `NULL`.453 *454 * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.455 */456XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed);457458/*!459 * @brief Consumes a block of @p input to an @ref XXH32_state_t.460 *461 * Call this to incrementally consume blocks of data.462 *463 * @param statePtr The state struct to update.464 * @param input The block of data to be hashed, at least @p length bytes in size.465 * @param length The length of @p input, in bytes.466 *467 * @pre468 * @p statePtr must not be `NULL`.469 * @pre470 * The memory between @p input and @p input + @p length must be valid,471 * readable, contiguous memory. However, if @p length is `0`, @p input may be472 * `NULL`. In C++, this also must be *TriviallyCopyable*.473 *474 * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.475 */476XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);477478/*!479 * @brief Returns the calculated hash value from an @ref XXH32_state_t.480 *481 * @note482 * Calling XXH32_digest() will not affect @p statePtr, so you can update,483 * digest, and update again.484 *485 * @param statePtr The state struct to calculate the hash from.486 *487 * @pre488 * @p statePtr must not be `NULL`.489 *490 * @return The calculated xxHash32 value from that state.491 */492XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);493494/******* Canonical representation *******/495496/*497 * The default return values from XXH functions are unsigned 32 and 64 bit498 * integers.499 * This the simplest and fastest format for further post-processing.500 *501 * However, this leaves open the question of what is the order on the byte level,502 * since little and big endian conventions will store the same number differently.503 *504 * The canonical representation settles this issue by mandating big-endian505 * convention, the same convention as human-readable numbers (large digits first).506 *507 * When writing hash values to storage, sending them over a network, or printing508 * them, it's highly recommended to use the canonical representation to ensure509 * portability across a wider range of systems, present and future.510 *511 * The following functions allow transformation of hash values to and from512 * canonical format.513 */514515/*!516 * @brief Canonical (big endian) representation of @ref XXH32_hash_t.517 */518typedef struct {519 unsigned char digest[4]; /*!< Hash bytes, big endian */520} XXH32_canonical_t;521522/*!523 * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t.524 *525 * @param dst The @ref XXH32_canonical_t pointer to be stored to.526 * @param hash The @ref XXH32_hash_t to be converted.527 *528 * @pre529 * @p dst must not be `NULL`.530 */531XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);532533/*!534 * @brief Converts an @ref XXH32_canonical_t to a native @ref XXH32_hash_t.535 *536 * @param src The @ref XXH32_canonical_t to convert.537 *538 * @pre539 * @p src must not be `NULL`.540 *541 * @return The converted hash.542 */543XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);544545546/*!547 * @}548 * @ingroup public549 * @{550 */551552#ifndef XXH_NO_LONG_LONG553/*-**********************************************************************554* 64-bit hash555************************************************************************/556#if defined(XXH_DOXYGEN) /* don't include <stdint.h> */557/*!558 * @brief An unsigned 64-bit integer.559 *560 * Not necessarily defined to `uint64_t` but functionally equivalent.561 */562typedef uint64_t XXH64_hash_t;563#elif !defined (__VMS) \564 && (defined (__cplusplus) \565 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )566# include <stdint.h>567 typedef uint64_t XXH64_hash_t;568#else569# include <limits.h>570# if defined(__LP64__) && ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL571 /* LP64 ABI says uint64_t is unsigned long */572 typedef unsigned long XXH64_hash_t;573# else574 /* the following type must have a width of 64-bit */575 typedef unsigned long long XXH64_hash_t;576# endif577#endif578579/*!580 * @}581 *582 * @defgroup xxh64_family XXH64 family583 * @ingroup public584 * @{585 * Contains functions used in the classic 64-bit xxHash algorithm.586 *587 * @note588 * XXH3 provides competitive speed for both 32-bit and 64-bit systems,589 * and offers true 64/128 bit hash results. It provides a superior level of590 * dispersion, and greatly reduces the risks of collisions.591 */592593594/*!595 * @brief Calculates the 64-bit hash of @p input using xxHash64.596 *597 * This function usually runs faster on 64-bit systems, but slower on 32-bit598 * systems (see benchmark).599 *600 * @param input The block of data to be hashed, at least @p length bytes in size.601 * @param length The length of @p input, in bytes.602 * @param seed The 64-bit seed to alter the hash's output predictably.603 *604 * @pre605 * The memory between @p input and @p input + @p length must be valid,606 * readable, contiguous memory. However, if @p length is `0`, @p input may be607 * `NULL`. In C++, this also must be *TriviallyCopyable*.608 *609 * @return The calculated 64-bit hash.610 *611 * @see612 * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():613 * Direct equivalents for the other variants of xxHash.614 * @see615 * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version.616 */617XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed);618619/******* Streaming *******/620/*!621 * @brief The opaque state struct for the XXH64 streaming API.622 *623 * @see XXH64_state_s for details.624 */625typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */626XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);627XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);628XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);629630XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed);631XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);632XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);633634/******* Canonical representation *******/635typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t;636XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);637XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);638639/*!640 * @}641 * ************************************************************************642 * @defgroup xxh3_family XXH3 family643 * @ingroup public644 * @{645 *646 * XXH3 is a more recent hash algorithm featuring:647 * - Improved speed for both small and large inputs648 * - True 64-bit and 128-bit outputs649 * - SIMD acceleration650 * - Improved 32-bit viability651 *652 * Speed analysis methodology is explained here:653 *654 * https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html655 *656 * Compared to XXH64, expect XXH3 to run approximately657 * ~2x faster on large inputs and >3x faster on small ones,658 * exact differences vary depending on platform.659 *660 * XXH3's speed benefits greatly from SIMD and 64-bit arithmetic,661 * but does not require it.662 * Any 32-bit and 64-bit targets that can run XXH32 smoothly663 * can run XXH3 at competitive speeds, even without vector support.664 * Further details are explained in the implementation.665 *666 * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8,667 * ZVector and scalar targets. This can be controlled via the XXH_VECTOR macro.668 *669 * XXH3 implementation is portable:670 * it has a generic C90 formulation that can be compiled on any platform,671 * all implementations generage exactly the same hash value on all platforms.672 * Starting from v0.8.0, it's also labelled "stable", meaning that673 * any future version will also generate the same hash value.674 *675 * XXH3 offers 2 variants, _64bits and _128bits.676 *677 * When only 64 bits are needed, prefer invoking the _64bits variant, as it678 * reduces the amount of mixing, resulting in faster speed on small inputs.679 * It's also generally simpler to manipulate a scalar return type than a struct.680 *681 * The API supports one-shot hashing, streaming mode, and custom secrets.682 */683684/*-**********************************************************************685* XXH3 64-bit variant686************************************************************************/687688/* XXH3_64bits():689 * default 64-bit variant, using default secret and default seed of 0.690 * It's the fastest variant. */691XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len);692693/*694 * XXH3_64bits_withSeed():695 * This variant generates a custom secret on the fly696 * based on default secret altered using the `seed` value.697 * While this operation is decently fast, note that it's not completely free.698 * Note: seed==0 produces the same results as XXH3_64bits().699 */700XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);701702/*!703 * The bare minimum size for a custom secret.704 *705 * @see706 * XXH3_64bits_withSecret(), XXH3_64bits_reset_withSecret(),707 * XXH3_128bits_withSecret(), XXH3_128bits_reset_withSecret().708 */709#define XXH3_SECRET_SIZE_MIN 136710711/*712 * XXH3_64bits_withSecret():713 * It's possible to provide any blob of bytes as a "secret" to generate the hash.714 * This makes it more difficult for an external actor to prepare an intentional collision.715 * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN).716 * However, the quality of produced hash values depends on secret's entropy.717 * Technically, the secret must look like a bunch of random bytes.718 * Avoid "trivial" or structured data such as repeated sequences or a text document.719 * Whenever unsure about the "randomness" of the blob of bytes,720 * consider relabelling it as a "custom seed" instead,721 * and employ "XXH3_generateSecret()" (see below)722 * to generate a high entropy secret derived from the custom seed.723 */724XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);725726727/******* Streaming *******/728/*729 * Streaming requires state maintenance.730 * This operation costs memory and CPU.731 * As a consequence, streaming is slower than one-shot hashing.732 * For better performance, prefer one-shot functions whenever applicable.733 */734735/*!736 * @brief The state struct for the XXH3 streaming API.737 *738 * @see XXH3_state_s for details.739 */740typedef struct XXH3_state_s XXH3_state_t;741XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void);742XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr);743XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state);744745/*746 * XXH3_64bits_reset():747 * Initialize with default parameters.748 * digest will be equivalent to `XXH3_64bits()`.749 */750XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr);751/*752 * XXH3_64bits_reset_withSeed():753 * Generate a custom secret from `seed`, and store it into `statePtr`.754 * digest will be equivalent to `XXH3_64bits_withSeed()`.755 */756XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);757/*758 * XXH3_64bits_reset_withSecret():759 * `secret` is referenced, it _must outlive_ the hash streaming session.760 * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`,761 * and the quality of produced hash values depends on secret's entropy762 * (secret's content should look like a bunch of random bytes).763 * When in doubt about the randomness of a candidate `secret`,764 * consider employing `XXH3_generateSecret()` instead (see below).765 */766XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);767768XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length);769XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr);770771/* note : canonical representation of XXH3 is the same as XXH64772 * since they both produce XXH64_hash_t values */773774775/*-**********************************************************************776* XXH3 128-bit variant777************************************************************************/778779/*!780 * @brief The return value from 128-bit hashes.781 *782 * Stored in little endian order, although the fields themselves are in native783 * endianness.784 */785typedef struct {786 XXH64_hash_t low64; /*!< `value & 0xFFFFFFFFFFFFFFFF` */787 XXH64_hash_t high64; /*!< `value >> 64` */788} XXH128_hash_t;789790XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len);791XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);792XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);793794/******* Streaming *******/795/*796 * Streaming requires state maintenance.797 * This operation costs memory and CPU.798 * As a consequence, streaming is slower than one-shot hashing.799 * For better performance, prefer one-shot functions whenever applicable.800 *801 * XXH3_128bits uses the same XXH3_state_t as XXH3_64bits().802 * Use already declared XXH3_createState() and XXH3_freeState().803 *804 * All reset and streaming functions have same meaning as their 64-bit counterpart.805 */806807XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr);808XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);809XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);810811XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length);812XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);813814/* Following helper functions make it possible to compare XXH128_hast_t values.815 * Since XXH128_hash_t is a structure, this capability is not offered by the language.816 * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */817818/*!819 * XXH128_isEqual():820 * Return: 1 if `h1` and `h2` are equal, 0 if they are not.821 */822XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2);823824/*!825 * XXH128_cmp():826 *827 * This comparator is compatible with stdlib's `qsort()`/`bsearch()`.828 *829 * return: >0 if *h128_1 > *h128_2830 * =0 if *h128_1 == *h128_2831 * <0 if *h128_1 < *h128_2832 */833XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2);834835836/******* Canonical representation *******/837typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t;838XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash);839XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src);840841842#endif /* XXH_NO_LONG_LONG */843844/*!845 * @}846 */847#endif /* XXHASH_H_5627135585666179 */848849850851#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742)852#define XXHASH_H_STATIC_13879238742853/* ****************************************************************************854 * This section contains declarations which are not guaranteed to remain stable.855 * They may change in future versions, becoming incompatible with a different856 * version of the library.857 * These declarations should only be used with static linking.858 * Never use them in association with dynamic linking!859 ***************************************************************************** */860861/*862 * These definitions are only present to allow static allocation863 * of XXH states, on stack or in a struct, for example.864 * Never **ever** access their members directly.865 */866867/*!868 * @internal869 * @brief Structure for XXH32 streaming API.870 *871 * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,872 * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is873 * an opaque type. This allows fields to safely be changed.874 *875 * Typedef'd to @ref XXH32_state_t.876 * Do not access the members of this struct directly.877 * @see XXH64_state_s, XXH3_state_s878 */879struct XXH32_state_s {880 XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */881 XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */882 XXH32_hash_t v1; /*!< First accumulator lane */883 XXH32_hash_t v2; /*!< Second accumulator lane */884 XXH32_hash_t v3; /*!< Third accumulator lane */885 XXH32_hash_t v4; /*!< Fourth accumulator lane */886 XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */887 XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */888 XXH32_hash_t reserved; /*!< Reserved field. Do not read or write to it, it may be removed. */889}; /* typedef'd to XXH32_state_t */890891892#ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */893894/*!895 * @internal896 * @brief Structure for XXH64 streaming API.897 *898 * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,899 * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is900 * an opaque type. This allows fields to safely be changed.901 *902 * Typedef'd to @ref XXH64_state_t.903 * Do not access the members of this struct directly.904 * @see XXH32_state_s, XXH3_state_s905 */906struct XXH64_state_s {907 XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */908 XXH64_hash_t v1; /*!< First accumulator lane */909 XXH64_hash_t v2; /*!< Second accumulator lane */910 XXH64_hash_t v3; /*!< Third accumulator lane */911 XXH64_hash_t v4; /*!< Fourth accumulator lane */912 XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */913 XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */914 XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/915 XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it, it may be removed. */916}; /* typedef'd to XXH64_state_t */917918#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11+ */919# include <stdalign.h>920# define XXH_ALIGN(n) alignas(n)921#elif defined(__GNUC__)922# define XXH_ALIGN(n) __attribute__ ((aligned(n)))923#elif defined(_MSC_VER)924# define XXH_ALIGN(n) __declspec(align(n))925#else926# define XXH_ALIGN(n) /* disabled */927#endif928929/* Old GCC versions only accept the attribute after the type in structures. */930#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \931 && defined(__GNUC__)932# define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align)933#else934# define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type935#endif936937/*!938 * @brief The size of the internal XXH3 buffer.939 *940 * This is the optimal update size for incremental hashing.941 *942 * @see XXH3_64b_update(), XXH3_128b_update().943 */944#define XXH3_INTERNALBUFFER_SIZE 256945946/*!947 * @brief Default size of the secret buffer (and @ref XXH3_kSecret).948 *949 * This is the size used in @ref XXH3_kSecret and the seeded functions.950 *951 * Not to be confused with @ref XXH3_SECRET_SIZE_MIN.952 */953#define XXH3_SECRET_DEFAULT_SIZE 192954955/*!956 * @internal957 * @brief Structure for XXH3 streaming API.958 *959 * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,960 * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is961 * an opaque type. This allows fields to safely be changed.962 *963 * @note **This structure has a strict alignment requirement of 64 bytes.** Do964 * not allocate this with `malloc()` or `new`, it will not be sufficiently965 * aligned. Use @ref XXH3_createState() and @ref XXH3_freeState(), or stack966 * allocation.967 *968 * Typedef'd to @ref XXH3_state_t.969 * Do not access the members of this struct directly.970 *971 * @see XXH3_INITSTATE() for stack initialization.972 * @see XXH3_createState(), XXH3_freeState().973 * @see XXH32_state_s, XXH64_state_s974 */975struct XXH3_state_s {976 XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]);977 /*!< The 8 accumulators. Similar to `vN` in @ref XXH32_state_s::v1 and @ref XXH64_state_s */978 XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]);979 /*!< Used to store a custom secret generated from a seed. */980 XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]);981 /*!< The internal buffer. @see XXH32_state_s::mem32 */982 XXH32_hash_t bufferedSize;983 /*!< The amount of memory in @ref buffer, @see XXH32_state_s::memsize */984 XXH32_hash_t reserved32;985 /*!< Reserved field. Needed for padding on 64-bit. */986 size_t nbStripesSoFar;987 /*!< Number or stripes processed. */988 XXH64_hash_t totalLen;989 /*!< Total length hashed. 64-bit even on 32-bit targets. */990 size_t nbStripesPerBlock;991 /*!< Number of stripes per block. */992 size_t secretLimit;993 /*!< Size of @ref customSecret or @ref extSecret */994 XXH64_hash_t seed;995 /*!< Seed for _withSeed variants. Must be zero otherwise, @see XXH3_INITSTATE() */996 XXH64_hash_t reserved64;997 /*!< Reserved field. */998 const unsigned char* extSecret;999 /*!< Reference to an external secret for the _withSecret variants, NULL1000 * for other variants. */1001 /* note: there may be some padding at the end due to alignment on 64 bytes */1002}; /* typedef'd to XXH3_state_t */10031004#undef XXH_ALIGN_MEMBER10051006/*!1007 * @brief Initializes a stack-allocated `XXH3_state_s`.1008 *1009 * When the @ref XXH3_state_t structure is merely emplaced on stack,1010 * it should be initialized with XXH3_INITSTATE() or a memset()1011 * in case its first reset uses XXH3_NNbits_reset_withSeed().1012 * This init can be omitted if the first reset uses default or _withSecret mode.1013 * This operation isn't necessary when the state is created with XXH3_createState().1014 * Note that this doesn't prepare the state for a streaming operation,1015 * it's still necessary to use XXH3_NNbits_reset*() afterwards.1016 */1017#define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; }101810191020/* === Experimental API === */1021/* Symbols defined below must be considered tied to a specific library version. */10221023/*1024 * XXH3_generateSecret():1025 *1026 * Derive a high-entropy secret from any user-defined content, named customSeed.1027 * The generated secret can be used in combination with `*_withSecret()` functions.1028 * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed,1029 * as it becomes much more difficult for an external actor to guess how to impact the calculation logic.1030 *1031 * The function accepts as input a custom seed of any length and any content,1032 * and derives from it a high-entropy secret of length XXH3_SECRET_DEFAULT_SIZE1033 * into an already allocated buffer secretBuffer.1034 * The generated secret is _always_ XXH_SECRET_DEFAULT_SIZE bytes long.1035 *1036 * The generated secret can then be used with any `*_withSecret()` variant.1037 * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`,1038 * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()`1039 * are part of this list. They all accept a `secret` parameter1040 * which must be very long for implementation reasons (>= XXH3_SECRET_SIZE_MIN)1041 * _and_ feature very high entropy (consist of random-looking bytes).1042 * These conditions can be a high bar to meet, so1043 * this function can be used to generate a secret of proper quality.1044 *1045 * customSeed can be anything. It can have any size, even small ones,1046 * and its content can be anything, even stupidly "low entropy" source such as a bunch of zeroes.1047 * The resulting `secret` will nonetheless provide all expected qualities.1048 *1049 * Supplying NULL as the customSeed copies the default secret into `secretBuffer`.1050 * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior.1051 */1052XXH_PUBLIC_API void XXH3_generateSecret(void* secretBuffer, const void* customSeed, size_t customSeedSize);105310541055/* simple short-cut to pre-selected XXH3_128bits variant */1056XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);105710581059#endif /* XXH_NO_LONG_LONG */1060#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)1061# define XXH_IMPLEMENTATION1062#endif10631064#endif /* defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) */106510661067/* ======================================================================== */1068/* ======================================================================== */1069/* ======================================================================== */107010711072/*-**********************************************************************1073 * xxHash implementation1074 *-**********************************************************************1075 * xxHash's implementation used to be hosted inside xxhash.c.1076 *1077 * However, inlining requires implementation to be visible to the compiler,1078 * hence be included alongside the header.1079 * Previously, implementation was hosted inside xxhash.c,1080 * which was then #included when inlining was activated.1081 * This construction created issues with a few build and install systems,1082 * as it required xxhash.c to be stored in /include directory.1083 *1084 * xxHash implementation is now directly integrated within xxhash.h.1085 * As a consequence, xxhash.c is no longer needed in /include.1086 *1087 * xxhash.c is still available and is still useful.1088 * In a "normal" setup, when xxhash is not inlined,1089 * xxhash.h only exposes the prototypes and public symbols,1090 * while xxhash.c can be built into an object file xxhash.o1091 * which can then be linked into the final binary.1092 ************************************************************************/10931094#if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \1095 || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387)1096# define XXH_IMPLEM_13a873738710971098/* *************************************1099* Tuning parameters1100***************************************/11011102/*!1103 * @defgroup tuning Tuning parameters1104 * @{1105 *1106 * Various macros to control xxHash's behavior.1107 */1108#ifdef XXH_DOXYGEN1109/*!1110 * @brief Define this to disable 64-bit code.1111 *1112 * Useful if only using the @ref xxh32_family and you have a strict C90 compiler.1113 */1114# define XXH_NO_LONG_LONG1115# undef XXH_NO_LONG_LONG /* don't actually */1116/*!1117 * @brief Controls how unaligned memory is accessed.1118 *1119 * By default, access to unaligned memory is controlled by `memcpy()`, which is1120 * safe and portable.1121 *1122 * Unfortunately, on some target/compiler combinations, the generated assembly1123 * is sub-optimal.1124 *1125 * The below switch allow selection of a different access method1126 * in the search for improved performance.1127 *1128 * @par Possible options:1129 *1130 * - `XXH_FORCE_MEMORY_ACCESS=0` (default): `memcpy`1131 * @par1132 * Use `memcpy()`. Safe and portable. Note that most modern compilers will1133 * eliminate the function call and treat it as an unaligned access.1134 *1135 * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((packed))`1136 * @par1137 * Depends on compiler extensions and is therefore not portable.1138 * This method is safe _if_ your compiler supports it,1139 * and *generally* as fast or faster than `memcpy`.1140 *1141 * - `XXH_FORCE_MEMORY_ACCESS=2`: Direct cast1142 * @par1143 * Casts directly and dereferences. This method doesn't depend on the1144 * compiler, but it violates the C standard as it directly dereferences an1145 * unaligned pointer. It can generate buggy code on targets which do not1146 * support unaligned memory accesses, but in some circumstances, it's the1147 * only known way to get the most performance.1148 *1149 * - `XXH_FORCE_MEMORY_ACCESS=3`: Byteshift1150 * @par1151 * Also portable. This can generate the best code on old compilers which don't1152 * inline small `memcpy()` calls, and it might also be faster on big-endian1153 * systems which lack a native byteswap instruction. However, some compilers1154 * will emit literal byteshifts even if the target supports unaligned access.1155 * .1156 *1157 * @warning1158 * Methods 1 and 2 rely on implementation-defined behavior. Use these with1159 * care, as what works on one compiler/platform/optimization level may cause1160 * another to read garbage data or even crash.1161 *1162 * See https://stackoverflow.com/a/32095106/646947 for details.1163 *1164 * Prefer these methods in priority order (0 > 3 > 1 > 2)1165 */1166# define XXH_FORCE_MEMORY_ACCESS 01167/*!1168 * @def XXH_ACCEPT_NULL_INPUT_POINTER1169 * @brief Whether to add explicit `NULL` checks.1170 *1171 * If the input pointer is `NULL` and the length is non-zero, xxHash's default1172 * behavior is to dereference it, triggering a segfault.1173 *1174 * When this macro is enabled, xxHash actively checks the input for a null pointer.1175 * If it is, the result for null input pointers is the same as a zero-length input.1176 */1177# define XXH_ACCEPT_NULL_INPUT_POINTER 01178/*!1179 * @def XXH_FORCE_ALIGN_CHECK1180 * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32()1181 * and XXH64() only).1182 *1183 * This is an important performance trick for architectures without decent1184 * unaligned memory access performance.1185 *1186 * It checks for input alignment, and when conditions are met, uses a "fast1187 * path" employing direct 32-bit/64-bit reads, resulting in _dramatically1188 * faster_ read speed.1189 *1190 * The check costs one initial branch per hash, which is generally negligible,1191 * but not zero.1192 *1193 * Moreover, it's not useful to generate an additional code path if memory1194 * access uses the same instruction for both aligned and unaligned1195 * addresses (e.g. x86 and aarch64).1196 *1197 * In these cases, the alignment check can be removed by setting this macro to 0.1198 * Then the code will always use unaligned memory access.1199 * Align check is automatically disabled on x86, x64 & arm64,1200 * which are platforms known to offer good unaligned memory accesses performance.1201 *1202 * This option does not affect XXH3 (only XXH32 and XXH64).1203 */1204# define XXH_FORCE_ALIGN_CHECK 012051206/*!1207 * @def XXH_NO_INLINE_HINTS1208 * @brief When non-zero, sets all functions to `static`.1209 *1210 * By default, xxHash tries to force the compiler to inline almost all internal1211 * functions.1212 *1213 * This can usually improve performance due to reduced jumping and improved1214 * constant folding, but significantly increases the size of the binary which1215 * might not be favorable.1216 *1217 * Additionally, sometimes the forced inlining can be detrimental to performance,1218 * depending on the architecture.1219 *1220 * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the1221 * compiler full control on whether to inline or not.1222 *1223 * When not optimizing (-O0), optimizing for size (-Os, -Oz), or using1224 * -fno-inline with GCC or Clang, this will automatically be defined.1225 */1226# define XXH_NO_INLINE_HINTS 012271228/*!1229 * @def XXH_REROLL1230 * @brief Whether to reroll `XXH32_finalize` and `XXH64_finalize`.1231 *1232 * For performance, `XXH32_finalize` and `XXH64_finalize` use an unrolled loop1233 * in the form of a switch statement.1234 *1235 * This is not always desirable, as it generates larger code, and depending on1236 * the architecture, may even be slower1237 *1238 * This is automatically defined with `-Os`/`-Oz` on GCC and Clang.1239 */1240# define XXH_REROLL 012411242/*!1243 * @internal1244 * @brief Redefines old internal names.1245 *1246 * For compatibility with code that uses xxHash's internals before the names1247 * were changed to improve namespacing. There is no other reason to use this.1248 */1249# define XXH_OLD_NAMES1250# undef XXH_OLD_NAMES /* don't actually use, it is ugly. */1251#endif /* XXH_DOXYGEN */1252/*!1253 * @}1254 */12551256#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */1257 /* prefer __packed__ structures (method 1) for gcc on armv7 and armv8 */1258# if !defined(__clang__) && ( \1259 (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \1260 (defined(__GNUC__) && (defined(__ARM_ARCH) && __ARM_ARCH >= 7)) )1261# define XXH_FORCE_MEMORY_ACCESS 11262# endif1263#endif12641265#ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */1266# define XXH_ACCEPT_NULL_INPUT_POINTER 01267#endif12681269#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */1270# if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \1271 || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */1272# define XXH_FORCE_ALIGN_CHECK 01273# else1274# define XXH_FORCE_ALIGN_CHECK 11275# endif1276#endif12771278#ifndef XXH_NO_INLINE_HINTS1279# if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \1280 || defined(__NO_INLINE__) /* -O0, -fno-inline */1281# define XXH_NO_INLINE_HINTS 11282# else1283# define XXH_NO_INLINE_HINTS 01284# endif1285#endif12861287#ifndef XXH_REROLL1288# if defined(__OPTIMIZE_SIZE__)1289# define XXH_REROLL 11290# else1291# define XXH_REROLL 01292# endif1293#endif12941295/*!1296 * @defgroup impl Implementation1297 * @{1298 */129913001301/* *************************************1302* Includes & Memory related functions1303***************************************/1304/*1305 * Modify the local functions below should you wish to use1306 * different memory routines for malloc() and free()1307 */1308#include <stdlib.h>13091310/*!1311 * @internal1312 * @brief Modify this function to use a different routine than malloc().1313 */1314static void* XXH_malloc(size_t s) { return malloc(s); }13151316/*!1317 * @internal1318 * @brief Modify this function to use a different routine than free().1319 */1320static void XXH_free(void* p) { free(p); }13211322#include <string.h>13231324/*!1325 * @internal1326 * @brief Modify this function to use a different routine than memcpy().1327 */1328static void* XXH_memcpy(void* dest, const void* src, size_t size)1329{1330 return memcpy(dest,src,size);1331}13321333#include <limits.h> /* ULLONG_MAX */133413351336/* *************************************1337* Compiler Specific Options1338***************************************/1339#ifdef _MSC_VER /* Visual Studio warning fix */1340# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */1341#endif13421343#if XXH_NO_INLINE_HINTS /* disable inlining hints */1344# if defined(__GNUC__)1345# define XXH_FORCE_INLINE static __attribute__((unused))1346# else1347# define XXH_FORCE_INLINE static1348# endif1349# define XXH_NO_INLINE static1350/* enable inlining hints */1351#elif defined(_MSC_VER) /* Visual Studio */1352# define XXH_FORCE_INLINE static __forceinline1353# define XXH_NO_INLINE static __declspec(noinline)1354#elif defined(__GNUC__)1355# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused))1356# define XXH_NO_INLINE static __attribute__((noinline))1357#elif defined (__cplusplus) \1358 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */1359# define XXH_FORCE_INLINE static inline1360# define XXH_NO_INLINE static1361#else1362# define XXH_FORCE_INLINE static1363# define XXH_NO_INLINE static1364#endif1365136613671368/* *************************************1369* Debug1370***************************************/1371/*!1372 * @ingroup tuning1373 * @def XXH_DEBUGLEVEL1374 * @brief Sets the debugging level.1375 *1376 * XXH_DEBUGLEVEL is expected to be defined externally, typically via the1377 * compiler's command line options. The value must be a number.1378 */1379#ifndef XXH_DEBUGLEVEL1380# ifdef DEBUGLEVEL /* backwards compat */1381# define XXH_DEBUGLEVEL DEBUGLEVEL1382# else1383# define XXH_DEBUGLEVEL 01384# endif1385#endif13861387#if (XXH_DEBUGLEVEL>=1)1388# include <assert.h> /* note: can still be disabled with NDEBUG */1389# define XXH_ASSERT(c) assert(c)1390#else1391# define XXH_ASSERT(c) ((void)0)1392#endif13931394/* note: use after variable declarations */1395#define XXH_STATIC_ASSERT(c) do { enum { XXH_sa = 1/(int)(!!(c)) }; } while (0)13961397/*!1398 * @internal1399 * @def XXH_COMPILER_GUARD(var)1400 * @brief Used to prevent unwanted optimizations for @p var.1401 *1402 * It uses an empty GCC inline assembly statement with a register constraint1403 * which forces @p var into a general purpose register (eg eax, ebx, ecx1404 * on x86) and marks it as modified.1405 *1406 * This is used in a few places to avoid unwanted autovectorization (e.g.1407 * XXH32_round()). All vectorization we want is explicit via intrinsics,1408 * and _usually_ isn't wanted elsewhere.1409 *1410 * We also use it to prevent unwanted constant folding for AArch64 in1411 * XXH3_initCustomSecret_scalar().1412 */1413#ifdef __GNUC__1414# define XXH_COMPILER_GUARD(var) __asm__ __volatile__("" : "+r" (var))1415#else1416# define XXH_COMPILER_GUARD(var) ((void)0)1417#endif14181419/* *************************************1420* Basic Types1421***************************************/1422#if !defined (__VMS) \1423 && (defined (__cplusplus) \1424 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )1425# include <stdint.h>1426 typedef uint8_t xxh_u8;1427#else1428 typedef unsigned char xxh_u8;1429#endif1430typedef XXH32_hash_t xxh_u32;14311432#ifdef XXH_OLD_NAMES1433# define BYTE xxh_u81434# define U8 xxh_u81435# define U32 xxh_u321436#endif14371438/* *** Memory access *** */14391440/*!1441 * @internal1442 * @fn xxh_u32 XXH_read32(const void* ptr)1443 * @brief Reads an unaligned 32-bit integer from @p ptr in native endianness.1444 *1445 * Affected by @ref XXH_FORCE_MEMORY_ACCESS.1446 *1447 * @param ptr The pointer to read from.1448 * @return The 32-bit native endian integer from the bytes at @p ptr.1449 */14501451/*!1452 * @internal1453 * @fn xxh_u32 XXH_readLE32(const void* ptr)1454 * @brief Reads an unaligned 32-bit little endian integer from @p ptr.1455 *1456 * Affected by @ref XXH_FORCE_MEMORY_ACCESS.1457 *1458 * @param ptr The pointer to read from.1459 * @return The 32-bit little endian integer from the bytes at @p ptr.1460 */14611462/*!1463 * @internal1464 * @fn xxh_u32 XXH_readBE32(const void* ptr)1465 * @brief Reads an unaligned 32-bit big endian integer from @p ptr.1466 *1467 * Affected by @ref XXH_FORCE_MEMORY_ACCESS.1468 *1469 * @param ptr The pointer to read from.1470 * @return The 32-bit big endian integer from the bytes at @p ptr.1471 */14721473/*!1474 * @internal1475 * @fn xxh_u32 XXH_readLE32_align(const void* ptr, XXH_alignment align)1476 * @brief Like @ref XXH_readLE32(), but has an option for aligned reads.1477 *1478 * Affected by @ref XXH_FORCE_MEMORY_ACCESS.1479 * Note that when @ref XXH_FORCE_ALIGN_CHECK == 0, the @p align parameter is1480 * always @ref XXH_alignment::XXH_unaligned.1481 *1482 * @param ptr The pointer to read from.1483 * @param align Whether @p ptr is aligned.1484 * @pre1485 * If @p align == @ref XXH_alignment::XXH_aligned, @p ptr must be 4 byte1486 * aligned.1487 * @return The 32-bit little endian integer from the bytes at @p ptr.1488 */14891490#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))1491/*1492 * Manual byteshift. Best for old compilers which don't inline memcpy.1493 * We actually directly use XXH_readLE32 and XXH_readBE32.1494 */1495#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))14961497/*1498 * Force direct memory access. Only works on CPU which support unaligned memory1499 * access in hardware.1500 */1501static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; }15021503#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))15041505/*1506 * __pack instructions are safer but compiler specific, hence potentially1507 * problematic for some compilers.1508 *1509 * Currently only defined for GCC and ICC.1510 */1511#ifdef XXH_OLD_NAMES1512typedef union { xxh_u32 u32; } __attribute__((packed)) unalign;1513#endif1514static xxh_u32 XXH_read32(const void* ptr)1515{1516 typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign;1517 return ((const xxh_unalign*)ptr)->u32;1518}15191520#else15211522/*1523 * Portable and safe solution. Generally efficient.1524 * see: https://stackoverflow.com/a/32095106/6469471525 */1526static xxh_u32 XXH_read32(const void* memPtr)1527{1528 xxh_u32 val;1529 memcpy(&val, memPtr, sizeof(val));1530 return val;1531}15321533#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */153415351536/* *** Endianness *** */1537typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;15381539/*!1540 * @ingroup tuning1541 * @def XXH_CPU_LITTLE_ENDIAN1542 * @brief Whether the target is little endian.1543 *1544 * Defined to 1 if the target is little endian, or 0 if it is big endian.1545 * It can be defined externally, for example on the compiler command line.1546 *1547 * If it is not defined, a runtime check (which is usually constant folded)1548 * is used instead.1549 *1550 * @note1551 * This is not necessarily defined to an integer constant.1552 *1553 * @see XXH_isLittleEndian() for the runtime check.1554 */1555#ifndef XXH_CPU_LITTLE_ENDIAN1556/*1557 * Try to detect endianness automatically, to avoid the nonstandard behavior1558 * in `XXH_isLittleEndian()`1559 */1560# if defined(_WIN32) /* Windows is always little endian */ \1561 || defined(__LITTLE_ENDIAN__) \1562 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)1563# define XXH_CPU_LITTLE_ENDIAN 11564# elif defined(__BIG_ENDIAN__) \1565 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)1566# define XXH_CPU_LITTLE_ENDIAN 01567# else1568/*!1569 * @internal1570 * @brief Runtime check for @ref XXH_CPU_LITTLE_ENDIAN.1571 *1572 * Most compilers will constant fold this.1573 */1574static int XXH_isLittleEndian(void)1575{1576 /*1577 * Portable and well-defined behavior.1578 * Don't use static: it is detrimental to performance.1579 */1580 const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 };1581 return one.c[0];1582}1583# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian()1584# endif1585#endif15861587158815891590/* ****************************************1591* Compiler-specific Functions and Macros1592******************************************/1593#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)15941595#ifdef __has_builtin1596# define XXH_HAS_BUILTIN(x) __has_builtin(x)1597#else1598# define XXH_HAS_BUILTIN(x) 01599#endif16001601/*!1602 * @internal1603 * @def XXH_rotl32(x,r)1604 * @brief 32-bit rotate left.1605 *1606 * @param x The 32-bit integer to be rotated.1607 * @param r The number of bits to rotate.1608 * @pre1609 * @p r > 0 && @p r < 321610 * @note1611 * @p x and @p r may be evaluated multiple times.1612 * @return The rotated result.1613 */1614#if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \1615 && XXH_HAS_BUILTIN(__builtin_rotateleft64)1616# define XXH_rotl32 __builtin_rotateleft321617# define XXH_rotl64 __builtin_rotateleft641618/* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */1619#elif defined(_MSC_VER)1620# define XXH_rotl32(x,r) _rotl(x,r)1621# define XXH_rotl64(x,r) _rotl64(x,r)1622#else1623# define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))1624# define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r))))1625#endif16261627/*!1628 * @internal1629 * @fn xxh_u32 XXH_swap32(xxh_u32 x)1630 * @brief A 32-bit byteswap.1631 *1632 * @param x The 32-bit integer to byteswap.1633 * @return @p x, byteswapped.1634 */1635#if defined(_MSC_VER) /* Visual Studio */1636# define XXH_swap32 _byteswap_ulong1637#elif XXH_GCC_VERSION >= 4031638# define XXH_swap32 __builtin_bswap321639#else1640static xxh_u32 XXH_swap32 (xxh_u32 x)1641{1642 return ((x << 24) & 0xff000000 ) |1643 ((x << 8) & 0x00ff0000 ) |1644 ((x >> 8) & 0x0000ff00 ) |1645 ((x >> 24) & 0x000000ff );1646}1647#endif164816491650/* ***************************1651* Memory reads1652*****************************/16531654/*!1655 * @internal1656 * @brief Enum to indicate whether a pointer is aligned.1657 */1658typedef enum {1659 XXH_aligned, /*!< Aligned */1660 XXH_unaligned /*!< Possibly unaligned */1661} XXH_alignment;16621663/*1664 * XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load.1665 *1666 * This is ideal for older compilers which don't inline memcpy.1667 */1668#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))16691670XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* memPtr)1671{1672 const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;1673 return bytePtr[0]1674 | ((xxh_u32)bytePtr[1] << 8)1675 | ((xxh_u32)bytePtr[2] << 16)1676 | ((xxh_u32)bytePtr[3] << 24);1677}16781679XXH_FORCE_INLINE xxh_u32 XXH_readBE32(const void* memPtr)1680{1681 const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;1682 return bytePtr[3]1683 | ((xxh_u32)bytePtr[2] << 8)1684 | ((xxh_u32)bytePtr[1] << 16)1685 | ((xxh_u32)bytePtr[0] << 24);1686}16871688#else1689XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr)1690{1691 return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));1692}16931694static xxh_u32 XXH_readBE32(const void* ptr)1695{1696 return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);1697}1698#endif16991700XXH_FORCE_INLINE xxh_u321701XXH_readLE32_align(const void* ptr, XXH_alignment align)1702{1703 if (align==XXH_unaligned) {1704 return XXH_readLE32(ptr);1705 } else {1706 return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr);1707 }1708}170917101711/* *************************************1712* Misc1713***************************************/1714/*! @ingroup public */1715XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }171617171718/* *******************************************************************1719* 32-bit hash functions1720*********************************************************************/1721/*!1722 * @}1723 * @defgroup xxh32_impl XXH32 implementation1724 * @ingroup impl1725 * @{1726 */1727 /* #define instead of static const, to be used as initializers */1728#define XXH_PRIME32_1 0x9E3779B1U /*!< 0b10011110001101110111100110110001 */1729#define XXH_PRIME32_2 0x85EBCA77U /*!< 0b10000101111010111100101001110111 */1730#define XXH_PRIME32_3 0xC2B2AE3DU /*!< 0b11000010101100101010111000111101 */1731#define XXH_PRIME32_4 0x27D4EB2FU /*!< 0b00100111110101001110101100101111 */1732#define XXH_PRIME32_5 0x165667B1U /*!< 0b00010110010101100110011110110001 */17331734#ifdef XXH_OLD_NAMES1735# define PRIME32_1 XXH_PRIME32_11736# define PRIME32_2 XXH_PRIME32_21737# define PRIME32_3 XXH_PRIME32_31738# define PRIME32_4 XXH_PRIME32_41739# define PRIME32_5 XXH_PRIME32_51740#endif17411742/*!1743 * @internal1744 * @brief Normal stripe processing routine.1745 *1746 * This shuffles the bits so that any bit from @p input impacts several bits in1747 * @p acc.1748 *1749 * @param acc The accumulator lane.1750 * @param input The stripe of input to mix.1751 * @return The mixed accumulator lane.1752 */1753static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)1754{1755 acc += input * XXH_PRIME32_2;1756 acc = XXH_rotl32(acc, 13);1757 acc *= XXH_PRIME32_1;1758#if (defined(__SSE4_1__) || defined(__aarch64__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)1759 /*1760 * UGLY HACK:1761 * A compiler fence is the only thing that prevents GCC and Clang from1762 * autovectorizing the XXH32 loop (pragmas and attributes don't work for some1763 * reason) without globally disabling SSE4.1.1764 *1765 * The reason we want to avoid vectorization is because despite working on1766 * 4 integers at a time, there are multiple factors slowing XXH32 down on1767 * SSE4:1768 * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on1769 * newer chips!) making it slightly slower to multiply four integers at1770 * once compared to four integers independently. Even when pmulld was1771 * fastest, Sandy/Ivy Bridge, it is still not worth it to go into SSE1772 * just to multiply unless doing a long operation.1773 *1774 * - Four instructions are required to rotate,1775 * movqda tmp, v // not required with VEX encoding1776 * pslld tmp, 13 // tmp <<= 131777 * psrld v, 19 // x >>= 191778 * por v, tmp // x |= tmp1779 * compared to one for scalar:1780 * roll v, 13 // reliably fast across the board1781 * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason1782 *1783 * - Instruction level parallelism is actually more beneficial here because1784 * the SIMD actually serializes this operation: While v1 is rotating, v21785 * can load data, while v3 can multiply. SSE forces them to operate1786 * together.1787 *1788 * This is also enabled on AArch64, as Clang autovectorizes it incorrectly1789 * and it is pointless writing a NEON implementation that is basically the1790 * same speed as scalar for XXH32.1791 */1792 XXH_COMPILER_GUARD(acc);1793#endif1794 return acc;1795}17961797/*!1798 * @internal1799 * @brief Mixes all bits to finalize the hash.1800 *1801 * The final mix ensures that all input bits have a chance to impact any bit in1802 * the output digest, resulting in an unbiased distribution.1803 *1804 * @param h32 The hash to avalanche.1805 * @return The avalanched hash.1806 */1807static xxh_u32 XXH32_avalanche(xxh_u32 h32)1808{1809 h32 ^= h32 >> 15;1810 h32 *= XXH_PRIME32_2;1811 h32 ^= h32 >> 13;1812 h32 *= XXH_PRIME32_3;1813 h32 ^= h32 >> 16;1814 return(h32);1815}18161817#define XXH_get32bits(p) XXH_readLE32_align(p, align)18181819/*!1820 * @internal1821 * @brief Processes the last 0-15 bytes of @p ptr.1822 *1823 * There may be up to 15 bytes remaining to consume from the input.1824 * This final stage will digest them to ensure that all input bytes are present1825 * in the final mix.1826 *1827 * @param h32 The hash to finalize.1828 * @param ptr The pointer to the remaining input.1829 * @param len The remaining length, modulo 16.1830 * @param align Whether @p ptr is aligned.1831 * @return The finalized hash.1832 */1833static xxh_u321834XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)1835{1836#define XXH_PROCESS1 do { \1837 h32 += (*ptr++) * XXH_PRIME32_5; \1838 h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \1839} while (0)18401841#define XXH_PROCESS4 do { \1842 h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \1843 ptr += 4; \1844 h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \1845} while (0)18461847 /* Compact rerolled version */1848 if (XXH_REROLL) {1849 len &= 15;1850 while (len >= 4) {1851 XXH_PROCESS4;1852 len -= 4;1853 }1854 while (len > 0) {1855 XXH_PROCESS1;1856 --len;1857 }1858 return XXH32_avalanche(h32);1859 } else {1860 switch(len&15) /* or switch(bEnd - p) */ {1861 case 12: XXH_PROCESS4;1862 /* fallthrough */1863 case 8: XXH_PROCESS4;1864 /* fallthrough */1865 case 4: XXH_PROCESS4;1866 return XXH32_avalanche(h32);18671868 case 13: XXH_PROCESS4;1869 /* fallthrough */1870 case 9: XXH_PROCESS4;1871 /* fallthrough */1872 case 5: XXH_PROCESS4;1873 XXH_PROCESS1;1874 return XXH32_avalanche(h32);18751876 case 14: XXH_PROCESS4;1877 /* fallthrough */1878 case 10: XXH_PROCESS4;1879 /* fallthrough */1880 case 6: XXH_PROCESS4;1881 XXH_PROCESS1;1882 XXH_PROCESS1;1883 return XXH32_avalanche(h32);18841885 case 15: XXH_PROCESS4;1886 /* fallthrough */1887 case 11: XXH_PROCESS4;1888 /* fallthrough */1889 case 7: XXH_PROCESS4;1890 /* fallthrough */1891 case 3: XXH_PROCESS1;1892 /* fallthrough */1893 case 2: XXH_PROCESS1;1894 /* fallthrough */1895 case 1: XXH_PROCESS1;1896 /* fallthrough */1897 case 0: return XXH32_avalanche(h32);1898 }1899 XXH_ASSERT(0);1900 return h32; /* reaching this point is deemed impossible */1901 }1902}19031904#ifdef XXH_OLD_NAMES1905# define PROCESS1 XXH_PROCESS11906# define PROCESS4 XXH_PROCESS41907#else1908# undef XXH_PROCESS11909# undef XXH_PROCESS41910#endif19111912/*!1913 * @internal1914 * @brief The implementation for @ref XXH32().1915 *1916 * @param input, len, seed Directly passed from @ref XXH32().1917 * @param align Whether @p input is aligned.1918 * @return The calculated hash.1919 */1920XXH_FORCE_INLINE xxh_u321921XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align)1922{1923 const xxh_u8* bEnd = input + len;1924 xxh_u32 h32;19251926#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)1927 if (input==NULL) {1928 len=0;1929 bEnd=input=(const xxh_u8*)(size_t)16;1930 }1931#endif19321933 if (len>=16) {1934 const xxh_u8* const limit = bEnd - 15;1935 xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2;1936 xxh_u32 v2 = seed + XXH_PRIME32_2;1937 xxh_u32 v3 = seed + 0;1938 xxh_u32 v4 = seed - XXH_PRIME32_1;19391940 do {1941 v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4;1942 v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4;1943 v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4;1944 v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4;1945 } while (input < limit);19461947 h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7)1948 + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);1949 } else {1950 h32 = seed + XXH_PRIME32_5;1951 }19521953 h32 += (xxh_u32)len;19541955 return XXH32_finalize(h32, input, len&15, align);1956}19571958/*! @ingroup xxh32_family */1959XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed)1960{1961#if 01962 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */1963 XXH32_state_t state;1964 XXH32_reset(&state, seed);1965 XXH32_update(&state, (const xxh_u8*)input, len);1966 return XXH32_digest(&state);1967#else1968 if (XXH_FORCE_ALIGN_CHECK) {1969 if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */1970 return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);1971 } }19721973 return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);1974#endif1975}1976197719781979/******* Hash streaming *******/1980/*!1981 * @ingroup xxh32_family1982 */1983XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)1984{1985 return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));1986}1987/*! @ingroup xxh32_family */1988XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)1989{1990 XXH_free(statePtr);1991 return XXH_OK;1992}19931994/*! @ingroup xxh32_family */1995XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)1996{1997 memcpy(dstState, srcState, sizeof(*dstState));1998}19992000/*! @ingroup xxh32_family */
Findings
✓ No findings reported for this file.