digest-xxhash 0.2.8 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/digest/xxhash/ext.c +1 -1
- data/ext/digest/xxhash/xxhash.h +890 -425
- data/lib/digest/xxhash/version.rb +1 -1
- metadata +3 -3
data/ext/digest/xxhash/xxhash.h
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* xxHash - Extremely Fast Hash algorithm
|
3
3
|
* Header File
|
4
|
-
* Copyright (C) 2012-
|
4
|
+
* Copyright (C) 2012-2023 Yann Collet
|
5
5
|
*
|
6
6
|
* BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
|
7
7
|
*
|
@@ -130,6 +130,7 @@
|
|
130
130
|
* }
|
131
131
|
* @endcode
|
132
132
|
*
|
133
|
+
*
|
133
134
|
* @anchor streaming_example
|
134
135
|
* **Streaming**
|
135
136
|
*
|
@@ -165,6 +166,77 @@
|
|
165
166
|
* }
|
166
167
|
* @endcode
|
167
168
|
*
|
169
|
+
* Streaming functions generate the xxHash value from an incremental input.
|
170
|
+
* This method is slower than single-call functions, due to state management.
|
171
|
+
* For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized.
|
172
|
+
*
|
173
|
+
* An XXH state must first be allocated using `XXH*_createState()`.
|
174
|
+
*
|
175
|
+
* Start a new hash by initializing the state with a seed using `XXH*_reset()`.
|
176
|
+
*
|
177
|
+
* Then, feed the hash state by calling `XXH*_update()` as many times as necessary.
|
178
|
+
*
|
179
|
+
* The function returns an error code, with 0 meaning OK, and any other value
|
180
|
+
* meaning there is an error.
|
181
|
+
*
|
182
|
+
* Finally, a hash value can be produced anytime, by using `XXH*_digest()`.
|
183
|
+
* This function returns the nn-bits hash as an int or long long.
|
184
|
+
*
|
185
|
+
* It's still possible to continue inserting input into the hash state after a
|
186
|
+
* digest, and generate new hash values later on by invoking `XXH*_digest()`.
|
187
|
+
*
|
188
|
+
* When done, release the state using `XXH*_freeState()`.
|
189
|
+
*
|
190
|
+
*
|
191
|
+
* @anchor canonical_representation_example
|
192
|
+
* **Canonical Representation**
|
193
|
+
*
|
194
|
+
* The default return values from XXH functions are unsigned 32, 64 and 128 bit
|
195
|
+
* integers.
|
196
|
+
* This the simplest and fastest format for further post-processing.
|
197
|
+
*
|
198
|
+
* However, this leaves open the question of what is the order on the byte level,
|
199
|
+
* since little and big endian conventions will store the same number differently.
|
200
|
+
*
|
201
|
+
* The canonical representation settles this issue by mandating big-endian
|
202
|
+
* convention, the same convention as human-readable numbers (large digits first).
|
203
|
+
*
|
204
|
+
* When writing hash values to storage, sending them over a network, or printing
|
205
|
+
* them, it's highly recommended to use the canonical representation to ensure
|
206
|
+
* portability across a wider range of systems, present and future.
|
207
|
+
*
|
208
|
+
* The following functions allow transformation of hash values to and from
|
209
|
+
* canonical format.
|
210
|
+
*
|
211
|
+
* XXH32_canonicalFromHash(), XXH32_hashFromCanonical(),
|
212
|
+
* XXH64_canonicalFromHash(), XXH64_hashFromCanonical(),
|
213
|
+
* XXH128_canonicalFromHash(), XXH128_hashFromCanonical(),
|
214
|
+
*
|
215
|
+
* @code{.c}
|
216
|
+
* #include <stdio.h>
|
217
|
+
* #include "xxhash.h"
|
218
|
+
*
|
219
|
+
* // Example for a function which prints XXH32_hash_t in human readable format
|
220
|
+
* void printXxh32(XXH32_hash_t hash)
|
221
|
+
* {
|
222
|
+
* XXH32_canonical_t cano;
|
223
|
+
* XXH32_canonicalFromHash(&cano, hash);
|
224
|
+
* size_t i;
|
225
|
+
* for(i = 0; i < sizeof(cano.digest); ++i) {
|
226
|
+
* printf("%02x", cano.digest[i]);
|
227
|
+
* }
|
228
|
+
* printf("\n");
|
229
|
+
* }
|
230
|
+
*
|
231
|
+
* // Example for a function which converts XXH32_canonical_t to XXH32_hash_t
|
232
|
+
* XXH32_hash_t convertCanonicalToXxh32(XXH32_canonical_t cano)
|
233
|
+
* {
|
234
|
+
* XXH32_hash_t hash = XXH32_hashFromCanonical(&cano);
|
235
|
+
* return hash;
|
236
|
+
* }
|
237
|
+
* @endcode
|
238
|
+
*
|
239
|
+
*
|
168
240
|
* @file xxhash.h
|
169
241
|
* xxHash prototypes and implementation
|
170
242
|
*/
|
@@ -261,7 +333,7 @@ extern "C" {
|
|
261
333
|
/* make all functions private */
|
262
334
|
# undef XXH_PUBLIC_API
|
263
335
|
# if defined(__GNUC__)
|
264
|
-
# define XXH_PUBLIC_API static __inline __attribute__((
|
336
|
+
# define XXH_PUBLIC_API static __inline __attribute__((__unused__))
|
265
337
|
# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
266
338
|
# define XXH_PUBLIC_API static inline
|
267
339
|
# elif defined(_MSC_VER)
|
@@ -373,7 +445,7 @@ extern "C" {
|
|
373
445
|
|
374
446
|
/*! @brief Marks a global symbol. */
|
375
447
|
#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
|
376
|
-
# if defined(
|
448
|
+
# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
|
377
449
|
# ifdef XXH_EXPORT
|
378
450
|
# define XXH_PUBLIC_API __declspec(dllexport)
|
379
451
|
# elif XXH_IMPORT
|
@@ -449,7 +521,7 @@ extern "C" {
|
|
449
521
|
|
450
522
|
/* specific declaration modes for Windows */
|
451
523
|
#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
|
452
|
-
# if defined(
|
524
|
+
# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
|
453
525
|
# ifdef XXH_EXPORT
|
454
526
|
# define XXH_PUBLIC_API __declspec(dllexport)
|
455
527
|
# elif XXH_IMPORT
|
@@ -461,9 +533,9 @@ extern "C" {
|
|
461
533
|
#endif
|
462
534
|
|
463
535
|
#if defined (__GNUC__)
|
464
|
-
# define XXH_CONSTF __attribute__((
|
465
|
-
# define XXH_PUREF __attribute__((
|
466
|
-
# define XXH_MALLOCF __attribute__((
|
536
|
+
# define XXH_CONSTF __attribute__((__const__))
|
537
|
+
# define XXH_PUREF __attribute__((__pure__))
|
538
|
+
# define XXH_MALLOCF __attribute__((__malloc__))
|
467
539
|
#else
|
468
540
|
# define XXH_CONSTF /* disable */
|
469
541
|
# define XXH_PUREF
|
@@ -475,7 +547,7 @@ extern "C" {
|
|
475
547
|
***************************************/
|
476
548
|
#define XXH_VERSION_MAJOR 0
|
477
549
|
#define XXH_VERSION_MINOR 8
|
478
|
-
#define XXH_VERSION_RELEASE
|
550
|
+
#define XXH_VERSION_RELEASE 3
|
479
551
|
/*! @brief Version number, encoded as two digits each */
|
480
552
|
#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
|
481
553
|
|
@@ -517,7 +589,11 @@ typedef uint32_t XXH32_hash_t;
|
|
517
589
|
#elif !defined (__VMS) \
|
518
590
|
&& (defined (__cplusplus) \
|
519
591
|
|| (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
|
520
|
-
#
|
592
|
+
# ifdef _AIX
|
593
|
+
# include <inttypes.h>
|
594
|
+
# else
|
595
|
+
# include <stdint.h>
|
596
|
+
# endif
|
521
597
|
typedef uint32_t XXH32_hash_t;
|
522
598
|
|
523
599
|
#else
|
@@ -551,10 +627,6 @@ typedef uint32_t XXH32_hash_t;
|
|
551
627
|
/*!
|
552
628
|
* @brief Calculates the 32-bit hash of @p input using xxHash32.
|
553
629
|
*
|
554
|
-
* Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s
|
555
|
-
*
|
556
|
-
* See @ref single_shot_example "Single Shot Example" for an example.
|
557
|
-
*
|
558
630
|
* @param input The block of data to be hashed, at least @p length bytes in size.
|
559
631
|
* @param length The length of @p input, in bytes.
|
560
632
|
* @param seed The 32-bit seed to alter the hash's output predictably.
|
@@ -564,63 +636,44 @@ typedef uint32_t XXH32_hash_t;
|
|
564
636
|
* readable, contiguous memory. However, if @p length is `0`, @p input may be
|
565
637
|
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
566
638
|
*
|
567
|
-
* @return The calculated 32-bit
|
639
|
+
* @return The calculated 32-bit xxHash32 value.
|
568
640
|
*
|
569
|
-
* @see
|
570
|
-
* XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():
|
571
|
-
* Direct equivalents for the other variants of xxHash.
|
572
|
-
* @see
|
573
|
-
* XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version.
|
641
|
+
* @see @ref single_shot_example "Single Shot Example" for an example.
|
574
642
|
*/
|
575
643
|
XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed);
|
576
644
|
|
577
645
|
#ifndef XXH_NO_STREAM
|
578
|
-
/*!
|
579
|
-
* Streaming functions generate the xxHash value from an incremental input.
|
580
|
-
* This method is slower than single-call functions, due to state management.
|
581
|
-
* For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized.
|
582
|
-
*
|
583
|
-
* An XXH state must first be allocated using `XXH*_createState()`.
|
584
|
-
*
|
585
|
-
* Start a new hash by initializing the state with a seed using `XXH*_reset()`.
|
586
|
-
*
|
587
|
-
* Then, feed the hash state by calling `XXH*_update()` as many times as necessary.
|
588
|
-
*
|
589
|
-
* The function returns an error code, with 0 meaning OK, and any other value
|
590
|
-
* meaning there is an error.
|
591
|
-
*
|
592
|
-
* Finally, a hash value can be produced anytime, by using `XXH*_digest()`.
|
593
|
-
* This function returns the nn-bits hash as an int or long long.
|
594
|
-
*
|
595
|
-
* It's still possible to continue inserting input into the hash state after a
|
596
|
-
* digest, and generate new hash values later on by invoking `XXH*_digest()`.
|
597
|
-
*
|
598
|
-
* When done, release the state using `XXH*_freeState()`.
|
599
|
-
*
|
600
|
-
* @see streaming_example at the top of @ref xxhash.h for an example.
|
601
|
-
*/
|
602
|
-
|
603
646
|
/*!
|
604
647
|
* @typedef struct XXH32_state_s XXH32_state_t
|
605
648
|
* @brief The opaque state struct for the XXH32 streaming API.
|
606
649
|
*
|
607
650
|
* @see XXH32_state_s for details.
|
651
|
+
* @see @ref streaming_example "Streaming Example"
|
608
652
|
*/
|
609
653
|
typedef struct XXH32_state_s XXH32_state_t;
|
610
654
|
|
611
655
|
/*!
|
612
656
|
* @brief Allocates an @ref XXH32_state_t.
|
613
657
|
*
|
614
|
-
*
|
615
|
-
* @return
|
658
|
+
* @return An allocated pointer of @ref XXH32_state_t on success.
|
659
|
+
* @return `NULL` on failure.
|
660
|
+
*
|
661
|
+
* @note Must be freed with XXH32_freeState().
|
662
|
+
*
|
663
|
+
* @see @ref streaming_example "Streaming Example"
|
616
664
|
*/
|
617
665
|
XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void);
|
618
666
|
/*!
|
619
667
|
* @brief Frees an @ref XXH32_state_t.
|
620
668
|
*
|
621
|
-
* Must be allocated with XXH32_createState().
|
622
669
|
* @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState().
|
623
|
-
*
|
670
|
+
*
|
671
|
+
* @return @ref XXH_OK.
|
672
|
+
*
|
673
|
+
* @note @p statePtr must be allocated with XXH32_createState().
|
674
|
+
*
|
675
|
+
* @see @ref streaming_example "Streaming Example"
|
676
|
+
*
|
624
677
|
*/
|
625
678
|
XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
|
626
679
|
/*!
|
@@ -636,23 +689,24 @@ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_
|
|
636
689
|
/*!
|
637
690
|
* @brief Resets an @ref XXH32_state_t to begin a new hash.
|
638
691
|
*
|
639
|
-
* This function resets and seeds a state. Call it before @ref XXH32_update().
|
640
|
-
*
|
641
692
|
* @param statePtr The state struct to reset.
|
642
693
|
* @param seed The 32-bit seed to alter the hash result predictably.
|
643
694
|
*
|
644
695
|
* @pre
|
645
696
|
* @p statePtr must not be `NULL`.
|
646
697
|
*
|
647
|
-
* @return @ref XXH_OK on success
|
698
|
+
* @return @ref XXH_OK on success.
|
699
|
+
* @return @ref XXH_ERROR on failure.
|
700
|
+
*
|
701
|
+
* @note This function resets and seeds a state. Call it before @ref XXH32_update().
|
702
|
+
*
|
703
|
+
* @see @ref streaming_example "Streaming Example"
|
648
704
|
*/
|
649
705
|
XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed);
|
650
706
|
|
651
707
|
/*!
|
652
708
|
* @brief Consumes a block of @p input to an @ref XXH32_state_t.
|
653
709
|
*
|
654
|
-
* Call this to incrementally consume blocks of data.
|
655
|
-
*
|
656
710
|
* @param statePtr The state struct to update.
|
657
711
|
* @param input The block of data to be hashed, at least @p length bytes in size.
|
658
712
|
* @param length The length of @p input, in bytes.
|
@@ -664,48 +718,36 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t
|
|
664
718
|
* readable, contiguous memory. However, if @p length is `0`, @p input may be
|
665
719
|
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
666
720
|
*
|
667
|
-
* @return @ref XXH_OK on success
|
721
|
+
* @return @ref XXH_OK on success.
|
722
|
+
* @return @ref XXH_ERROR on failure.
|
723
|
+
*
|
724
|
+
* @note Call this to incrementally consume blocks of data.
|
725
|
+
*
|
726
|
+
* @see @ref streaming_example "Streaming Example"
|
668
727
|
*/
|
669
728
|
XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
|
670
729
|
|
671
730
|
/*!
|
672
731
|
* @brief Returns the calculated hash value from an @ref XXH32_state_t.
|
673
732
|
*
|
674
|
-
* @note
|
675
|
-
* Calling XXH32_digest() will not affect @p statePtr, so you can update,
|
676
|
-
* digest, and update again.
|
677
|
-
*
|
678
733
|
* @param statePtr The state struct to calculate the hash from.
|
679
734
|
*
|
680
735
|
* @pre
|
681
736
|
* @p statePtr must not be `NULL`.
|
682
737
|
*
|
683
|
-
* @return The calculated xxHash32 value from that state.
|
738
|
+
* @return The calculated 32-bit xxHash32 value from that state.
|
739
|
+
*
|
740
|
+
* @note
|
741
|
+
* Calling XXH32_digest() will not affect @p statePtr, so you can update,
|
742
|
+
* digest, and update again.
|
743
|
+
*
|
744
|
+
* @see @ref streaming_example "Streaming Example"
|
684
745
|
*/
|
685
746
|
XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
|
686
747
|
#endif /* !XXH_NO_STREAM */
|
687
748
|
|
688
749
|
/******* Canonical representation *******/
|
689
750
|
|
690
|
-
/*
|
691
|
-
* The default return values from XXH functions are unsigned 32 and 64 bit
|
692
|
-
* integers.
|
693
|
-
* This the simplest and fastest format for further post-processing.
|
694
|
-
*
|
695
|
-
* However, this leaves open the question of what is the order on the byte level,
|
696
|
-
* since little and big endian conventions will store the same number differently.
|
697
|
-
*
|
698
|
-
* The canonical representation settles this issue by mandating big-endian
|
699
|
-
* convention, the same convention as human-readable numbers (large digits first).
|
700
|
-
*
|
701
|
-
* When writing hash values to storage, sending them over a network, or printing
|
702
|
-
* them, it's highly recommended to use the canonical representation to ensure
|
703
|
-
* portability across a wider range of systems, present and future.
|
704
|
-
*
|
705
|
-
* The following functions allow transformation of hash values to and from
|
706
|
-
* canonical format.
|
707
|
-
*/
|
708
|
-
|
709
751
|
/*!
|
710
752
|
* @brief Canonical (big endian) representation of @ref XXH32_hash_t.
|
711
753
|
*/
|
@@ -716,11 +758,13 @@ typedef struct {
|
|
716
758
|
/*!
|
717
759
|
* @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t.
|
718
760
|
*
|
719
|
-
* @param dst
|
761
|
+
* @param dst The @ref XXH32_canonical_t pointer to be stored to.
|
720
762
|
* @param hash The @ref XXH32_hash_t to be converted.
|
721
763
|
*
|
722
764
|
* @pre
|
723
765
|
* @p dst must not be `NULL`.
|
766
|
+
*
|
767
|
+
* @see @ref canonical_representation_example "Canonical Representation Example"
|
724
768
|
*/
|
725
769
|
XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
|
726
770
|
|
@@ -733,6 +777,8 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t
|
|
733
777
|
* @p src must not be `NULL`.
|
734
778
|
*
|
735
779
|
* @return The converted hash.
|
780
|
+
*
|
781
|
+
* @see @ref canonical_representation_example "Canonical Representation Example"
|
736
782
|
*/
|
737
783
|
XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
|
738
784
|
|
@@ -794,7 +840,7 @@ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canoni
|
|
794
840
|
* As of writing this, only supported by clang.
|
795
841
|
*/
|
796
842
|
#if XXH_HAS_ATTRIBUTE(noescape)
|
797
|
-
# define XXH_NOESCAPE __attribute__((
|
843
|
+
# define XXH_NOESCAPE __attribute__((__noescape__))
|
798
844
|
#else
|
799
845
|
# define XXH_NOESCAPE
|
800
846
|
#endif
|
@@ -821,7 +867,11 @@ typedef uint64_t XXH64_hash_t;
|
|
821
867
|
#elif !defined (__VMS) \
|
822
868
|
&& (defined (__cplusplus) \
|
823
869
|
|| (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
|
824
|
-
#
|
870
|
+
# ifdef _AIX
|
871
|
+
# include <inttypes.h>
|
872
|
+
# else
|
873
|
+
# include <stdint.h>
|
874
|
+
# endif
|
825
875
|
typedef uint64_t XXH64_hash_t;
|
826
876
|
#else
|
827
877
|
# include <limits.h>
|
@@ -851,9 +901,6 @@ typedef uint64_t XXH64_hash_t;
|
|
851
901
|
/*!
|
852
902
|
* @brief Calculates the 64-bit hash of @p input using xxHash64.
|
853
903
|
*
|
854
|
-
* This function usually runs faster on 64-bit systems, but slower on 32-bit
|
855
|
-
* systems (see benchmark).
|
856
|
-
*
|
857
904
|
* @param input The block of data to be hashed, at least @p length bytes in size.
|
858
905
|
* @param length The length of @p input, in bytes.
|
859
906
|
* @param seed The 64-bit seed to alter the hash's output predictably.
|
@@ -863,13 +910,9 @@ typedef uint64_t XXH64_hash_t;
|
|
863
910
|
* readable, contiguous memory. However, if @p length is `0`, @p input may be
|
864
911
|
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
865
912
|
*
|
866
|
-
* @return The calculated 64-bit
|
913
|
+
* @return The calculated 64-bit xxHash64 value.
|
867
914
|
*
|
868
|
-
* @see
|
869
|
-
* XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():
|
870
|
-
* Direct equivalents for the other variants of xxHash.
|
871
|
-
* @see
|
872
|
-
* XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version.
|
915
|
+
* @see @ref single_shot_example "Single Shot Example" for an example.
|
873
916
|
*/
|
874
917
|
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed);
|
875
918
|
|
@@ -879,23 +922,32 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size
|
|
879
922
|
* @brief The opaque state struct for the XXH64 streaming API.
|
880
923
|
*
|
881
924
|
* @see XXH64_state_s for details.
|
925
|
+
* @see @ref streaming_example "Streaming Example"
|
882
926
|
*/
|
883
927
|
typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
|
884
928
|
|
885
929
|
/*!
|
886
930
|
* @brief Allocates an @ref XXH64_state_t.
|
887
931
|
*
|
888
|
-
*
|
889
|
-
* @return
|
932
|
+
* @return An allocated pointer of @ref XXH64_state_t on success.
|
933
|
+
* @return `NULL` on failure.
|
934
|
+
*
|
935
|
+
* @note Must be freed with XXH64_freeState().
|
936
|
+
*
|
937
|
+
* @see @ref streaming_example "Streaming Example"
|
890
938
|
*/
|
891
939
|
XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void);
|
892
940
|
|
893
941
|
/*!
|
894
942
|
* @brief Frees an @ref XXH64_state_t.
|
895
943
|
*
|
896
|
-
* Must be allocated with XXH64_createState().
|
897
944
|
* @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState().
|
898
|
-
*
|
945
|
+
*
|
946
|
+
* @return @ref XXH_OK.
|
947
|
+
*
|
948
|
+
* @note @p statePtr must be allocated with XXH64_createState().
|
949
|
+
*
|
950
|
+
* @see @ref streaming_example "Streaming Example"
|
899
951
|
*/
|
900
952
|
XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
|
901
953
|
|
@@ -912,23 +964,24 @@ XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const
|
|
912
964
|
/*!
|
913
965
|
* @brief Resets an @ref XXH64_state_t to begin a new hash.
|
914
966
|
*
|
915
|
-
* This function resets and seeds a state. Call it before @ref XXH64_update().
|
916
|
-
*
|
917
967
|
* @param statePtr The state struct to reset.
|
918
968
|
* @param seed The 64-bit seed to alter the hash result predictably.
|
919
969
|
*
|
920
970
|
* @pre
|
921
971
|
* @p statePtr must not be `NULL`.
|
922
972
|
*
|
923
|
-
* @return @ref XXH_OK on success
|
973
|
+
* @return @ref XXH_OK on success.
|
974
|
+
* @return @ref XXH_ERROR on failure.
|
975
|
+
*
|
976
|
+
* @note This function resets and seeds a state. Call it before @ref XXH64_update().
|
977
|
+
*
|
978
|
+
* @see @ref streaming_example "Streaming Example"
|
924
979
|
*/
|
925
980
|
XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed);
|
926
981
|
|
927
982
|
/*!
|
928
983
|
* @brief Consumes a block of @p input to an @ref XXH64_state_t.
|
929
984
|
*
|
930
|
-
* Call this to incrementally consume blocks of data.
|
931
|
-
*
|
932
985
|
* @param statePtr The state struct to update.
|
933
986
|
* @param input The block of data to be hashed, at least @p length bytes in size.
|
934
987
|
* @param length The length of @p input, in bytes.
|
@@ -940,23 +993,30 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr,
|
|
940
993
|
* readable, contiguous memory. However, if @p length is `0`, @p input may be
|
941
994
|
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
942
995
|
*
|
943
|
-
* @return @ref XXH_OK on success
|
996
|
+
* @return @ref XXH_OK on success.
|
997
|
+
* @return @ref XXH_ERROR on failure.
|
998
|
+
*
|
999
|
+
* @note Call this to incrementally consume blocks of data.
|
1000
|
+
*
|
1001
|
+
* @see @ref streaming_example "Streaming Example"
|
944
1002
|
*/
|
945
1003
|
XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length);
|
946
1004
|
|
947
1005
|
/*!
|
948
1006
|
* @brief Returns the calculated hash value from an @ref XXH64_state_t.
|
949
1007
|
*
|
950
|
-
* @note
|
951
|
-
* Calling XXH64_digest() will not affect @p statePtr, so you can update,
|
952
|
-
* digest, and update again.
|
953
|
-
*
|
954
1008
|
* @param statePtr The state struct to calculate the hash from.
|
955
1009
|
*
|
956
1010
|
* @pre
|
957
1011
|
* @p statePtr must not be `NULL`.
|
958
1012
|
*
|
959
|
-
* @return The calculated xxHash64 value from that state.
|
1013
|
+
* @return The calculated 64-bit xxHash64 value from that state.
|
1014
|
+
*
|
1015
|
+
* @note
|
1016
|
+
* Calling XXH64_digest() will not affect @p statePtr, so you can update,
|
1017
|
+
* digest, and update again.
|
1018
|
+
*
|
1019
|
+
* @see @ref streaming_example "Streaming Example"
|
960
1020
|
*/
|
961
1021
|
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr);
|
962
1022
|
#endif /* !XXH_NO_STREAM */
|
@@ -975,6 +1035,8 @@ typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t
|
|
975
1035
|
*
|
976
1036
|
* @pre
|
977
1037
|
* @p dst must not be `NULL`.
|
1038
|
+
*
|
1039
|
+
* @see @ref canonical_representation_example "Canonical Representation Example"
|
978
1040
|
*/
|
979
1041
|
XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash);
|
980
1042
|
|
@@ -987,6 +1049,8 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst,
|
|
987
1049
|
* @p src must not be `NULL`.
|
988
1050
|
*
|
989
1051
|
* @return The converted hash.
|
1052
|
+
*
|
1053
|
+
* @see @ref canonical_representation_example "Canonical Representation Example"
|
990
1054
|
*/
|
991
1055
|
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src);
|
992
1056
|
|
@@ -1046,40 +1110,74 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const
|
|
1046
1110
|
*
|
1047
1111
|
* The API supports one-shot hashing, streaming mode, and custom secrets.
|
1048
1112
|
*/
|
1113
|
+
|
1114
|
+
/*!
|
1115
|
+
* @ingroup tuning
|
1116
|
+
* @brief Possible values for @ref XXH_VECTOR.
|
1117
|
+
*
|
1118
|
+
* Unless set explicitly, determined automatically.
|
1119
|
+
*/
|
1120
|
+
# define XXH_SCALAR 0 /*!< Portable scalar version */
|
1121
|
+
# define XXH_SSE2 1 /*!< SSE2 for Pentium 4, Opteron, all x86_64. */
|
1122
|
+
# define XXH_AVX2 2 /*!< AVX2 for Haswell and Bulldozer */
|
1123
|
+
# define XXH_AVX512 3 /*!< AVX512 for Skylake and Icelake */
|
1124
|
+
# define XXH_NEON 4 /*!< NEON for most ARMv7-A, all AArch64, and WASM SIMD128 */
|
1125
|
+
# define XXH_VSX 5 /*!< VSX and ZVector for POWER8/z13 (64-bit) */
|
1126
|
+
# define XXH_SVE 6 /*!< SVE for some ARMv8-A and ARMv9-A */
|
1127
|
+
# define XXH_LSX 7 /*!< LSX (128-bit SIMD) for LoongArch64 */
|
1128
|
+
|
1129
|
+
|
1049
1130
|
/*-**********************************************************************
|
1050
1131
|
* XXH3 64-bit variant
|
1051
1132
|
************************************************************************/
|
1052
1133
|
|
1053
1134
|
/*!
|
1054
|
-
* @brief 64-bit unseeded variant of XXH3.
|
1135
|
+
* @brief Calculates 64-bit unseeded variant of XXH3 hash of @p input.
|
1055
1136
|
*
|
1056
|
-
*
|
1057
|
-
*
|
1058
|
-
*
|
1137
|
+
* @param input The block of data to be hashed, at least @p length bytes in size.
|
1138
|
+
* @param length The length of @p input, in bytes.
|
1139
|
+
*
|
1140
|
+
* @pre
|
1141
|
+
* The memory between @p input and @p input + @p length must be valid,
|
1142
|
+
* readable, contiguous memory. However, if @p length is `0`, @p input may be
|
1143
|
+
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
1144
|
+
*
|
1145
|
+
* @return The calculated 64-bit XXH3 hash value.
|
1146
|
+
*
|
1147
|
+
* @note
|
1148
|
+
* This is equivalent to @ref XXH3_64bits_withSeed() with a seed of `0`, however
|
1149
|
+
* it may have slightly better performance due to constant propagation of the
|
1150
|
+
* defaults.
|
1059
1151
|
*
|
1060
|
-
* @see
|
1061
|
-
* XXH32(), XXH64(), XXH3_128bits(): equivalent for the other xxHash algorithms
|
1062
1152
|
* @see
|
1063
1153
|
* XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants
|
1064
|
-
* @see
|
1065
|
-
* XXH3_64bits_reset(), XXH3_64bits_update(), XXH3_64bits_digest(): Streaming version.
|
1154
|
+
* @see @ref single_shot_example "Single Shot Example" for an example.
|
1066
1155
|
*/
|
1067
1156
|
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length);
|
1068
1157
|
|
1069
1158
|
/*!
|
1070
|
-
* @brief 64-bit seeded variant of XXH3
|
1159
|
+
* @brief Calculates 64-bit seeded variant of XXH3 hash of @p input.
|
1071
1160
|
*
|
1072
|
-
*
|
1073
|
-
*
|
1161
|
+
* @param input The block of data to be hashed, at least @p length bytes in size.
|
1162
|
+
* @param length The length of @p input, in bytes.
|
1163
|
+
* @param seed The 64-bit seed to alter the hash result predictably.
|
1074
1164
|
*
|
1075
|
-
*
|
1165
|
+
* @pre
|
1166
|
+
* The memory between @p input and @p input + @p length must be valid,
|
1167
|
+
* readable, contiguous memory. However, if @p length is `0`, @p input may be
|
1168
|
+
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
1169
|
+
*
|
1170
|
+
* @return The calculated 64-bit XXH3 hash value.
|
1076
1171
|
*
|
1077
1172
|
* @note
|
1078
1173
|
* seed == 0 produces the same results as @ref XXH3_64bits().
|
1079
1174
|
*
|
1080
|
-
*
|
1081
|
-
* @
|
1082
|
-
*
|
1175
|
+
* This variant generates a custom secret on the fly based on default secret
|
1176
|
+
* altered using the @p seed value.
|
1177
|
+
*
|
1178
|
+
* While this operation is decently fast, note that it's not completely free.
|
1179
|
+
*
|
1180
|
+
* @see @ref single_shot_example "Single Shot Example" for an example.
|
1083
1181
|
*/
|
1084
1182
|
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed);
|
1085
1183
|
|
@@ -1093,22 +1191,36 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const vo
|
|
1093
1191
|
#define XXH3_SECRET_SIZE_MIN 136
|
1094
1192
|
|
1095
1193
|
/*!
|
1096
|
-
* @brief 64-bit variant of XXH3 with a custom "secret".
|
1194
|
+
* @brief Calculates 64-bit variant of XXH3 with a custom "secret".
|
1195
|
+
*
|
1196
|
+
* @param data The block of data to be hashed, at least @p len bytes in size.
|
1197
|
+
* @param len The length of @p data, in bytes.
|
1198
|
+
* @param secret The secret data.
|
1199
|
+
* @param secretSize The length of @p secret, in bytes.
|
1200
|
+
*
|
1201
|
+
* @return The calculated 64-bit XXH3 hash value.
|
1202
|
+
*
|
1203
|
+
* @pre
|
1204
|
+
* The memory between @p data and @p data + @p len must be valid,
|
1205
|
+
* readable, contiguous memory. However, if @p length is `0`, @p data may be
|
1206
|
+
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
1097
1207
|
*
|
1098
1208
|
* It's possible to provide any blob of bytes as a "secret" to generate the hash.
|
1099
1209
|
* This makes it more difficult for an external actor to prepare an intentional collision.
|
1100
|
-
* The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN).
|
1210
|
+
* The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN).
|
1101
1211
|
* However, the quality of the secret impacts the dispersion of the hash algorithm.
|
1102
1212
|
* Therefore, the secret _must_ look like a bunch of random bytes.
|
1103
1213
|
* Avoid "trivial" or structured data such as repeated sequences or a text document.
|
1104
1214
|
* Whenever in doubt about the "randomness" of the blob of bytes,
|
1105
|
-
* consider employing
|
1215
|
+
* consider employing @ref XXH3_generateSecret() instead (see below).
|
1106
1216
|
* It will generate a proper high entropy secret derived from the blob of bytes.
|
1107
1217
|
* Another advantage of using XXH3_generateSecret() is that
|
1108
1218
|
* it guarantees that all bits within the initial blob of bytes
|
1109
1219
|
* will impact every bit of the output.
|
1110
1220
|
* This is not necessarily the case when using the blob of bytes directly
|
1111
1221
|
* because, when hashing _small_ inputs, only a portion of the secret is employed.
|
1222
|
+
*
|
1223
|
+
* @see @ref single_shot_example "Single Shot Example" for an example.
|
1112
1224
|
*/
|
1113
1225
|
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize);
|
1114
1226
|
|
@@ -1123,9 +1235,10 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const
|
|
1123
1235
|
*/
|
1124
1236
|
|
1125
1237
|
/*!
|
1126
|
-
* @brief The state struct for the XXH3 streaming API.
|
1238
|
+
* @brief The opaque state struct for the XXH3 streaming API.
|
1127
1239
|
*
|
1128
1240
|
* @see XXH3_state_s for details.
|
1241
|
+
* @see @ref streaming_example "Streaming Example"
|
1129
1242
|
*/
|
1130
1243
|
typedef struct XXH3_state_s XXH3_state_t;
|
1131
1244
|
XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void);
|
@@ -1144,15 +1257,20 @@ XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOE
|
|
1144
1257
|
/*!
|
1145
1258
|
* @brief Resets an @ref XXH3_state_t to begin a new hash.
|
1146
1259
|
*
|
1147
|
-
* This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_64bits_update().
|
1148
|
-
* Digest will be equivalent to `XXH3_64bits()`.
|
1149
|
-
*
|
1150
1260
|
* @param statePtr The state struct to reset.
|
1151
1261
|
*
|
1152
1262
|
* @pre
|
1153
1263
|
* @p statePtr must not be `NULL`.
|
1154
1264
|
*
|
1155
|
-
* @return @ref XXH_OK on success
|
1265
|
+
* @return @ref XXH_OK on success.
|
1266
|
+
* @return @ref XXH_ERROR on failure.
|
1267
|
+
*
|
1268
|
+
* @note
|
1269
|
+
* - This function resets `statePtr` and generate a secret with default parameters.
|
1270
|
+
* - Call this function before @ref XXH3_64bits_update().
|
1271
|
+
* - Digest will be equivalent to `XXH3_64bits()`.
|
1272
|
+
*
|
1273
|
+
* @see @ref streaming_example "Streaming Example"
|
1156
1274
|
*
|
1157
1275
|
*/
|
1158
1276
|
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr);
|
@@ -1160,36 +1278,54 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* stateP
|
|
1160
1278
|
/*!
|
1161
1279
|
* @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash.
|
1162
1280
|
*
|
1163
|
-
* This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_64bits_update().
|
1164
|
-
* Digest will be equivalent to `XXH3_64bits_withSeed()`.
|
1165
|
-
*
|
1166
1281
|
* @param statePtr The state struct to reset.
|
1167
|
-
* @param seed The 64-bit seed to alter the
|
1282
|
+
* @param seed The 64-bit seed to alter the hash result predictably.
|
1168
1283
|
*
|
1169
1284
|
* @pre
|
1170
1285
|
* @p statePtr must not be `NULL`.
|
1171
1286
|
*
|
1172
|
-
* @return @ref XXH_OK on success
|
1287
|
+
* @return @ref XXH_OK on success.
|
1288
|
+
* @return @ref XXH_ERROR on failure.
|
1289
|
+
*
|
1290
|
+
* @note
|
1291
|
+
* - This function resets `statePtr` and generate a secret from `seed`.
|
1292
|
+
* - Call this function before @ref XXH3_64bits_update().
|
1293
|
+
* - Digest will be equivalent to `XXH3_64bits_withSeed()`.
|
1294
|
+
*
|
1295
|
+
* @see @ref streaming_example "Streaming Example"
|
1173
1296
|
*
|
1174
1297
|
*/
|
1175
1298
|
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed);
|
1176
1299
|
|
1177
1300
|
/*!
|
1178
|
-
*
|
1179
|
-
*
|
1180
|
-
*
|
1301
|
+
* @brief Resets an @ref XXH3_state_t with secret data to begin a new hash.
|
1302
|
+
*
|
1303
|
+
* @param statePtr The state struct to reset.
|
1304
|
+
* @param secret The secret data.
|
1305
|
+
* @param secretSize The length of @p secret, in bytes.
|
1306
|
+
*
|
1307
|
+
* @pre
|
1308
|
+
* @p statePtr must not be `NULL`.
|
1309
|
+
*
|
1310
|
+
* @return @ref XXH_OK on success.
|
1311
|
+
* @return @ref XXH_ERROR on failure.
|
1312
|
+
*
|
1313
|
+
* @note
|
1314
|
+
* `secret` is referenced, it _must outlive_ the hash streaming session.
|
1315
|
+
*
|
1316
|
+
* Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN,
|
1181
1317
|
* and the quality of produced hash values depends on secret's entropy
|
1182
1318
|
* (secret's content should look like a bunch of random bytes).
|
1183
1319
|
* When in doubt about the randomness of a candidate `secret`,
|
1184
1320
|
* consider employing `XXH3_generateSecret()` instead (see below).
|
1321
|
+
*
|
1322
|
+
* @see @ref streaming_example "Streaming Example"
|
1185
1323
|
*/
|
1186
1324
|
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize);
|
1187
1325
|
|
1188
1326
|
/*!
|
1189
1327
|
* @brief Consumes a block of @p input to an @ref XXH3_state_t.
|
1190
1328
|
*
|
1191
|
-
* Call this to incrementally consume blocks of data.
|
1192
|
-
*
|
1193
1329
|
* @param statePtr The state struct to update.
|
1194
1330
|
* @param input The block of data to be hashed, at least @p length bytes in size.
|
1195
1331
|
* @param length The length of @p input, in bytes.
|
@@ -1201,23 +1337,30 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_stat
|
|
1201
1337
|
* readable, contiguous memory. However, if @p length is `0`, @p input may be
|
1202
1338
|
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
1203
1339
|
*
|
1204
|
-
* @return @ref XXH_OK on success
|
1340
|
+
* @return @ref XXH_OK on success.
|
1341
|
+
* @return @ref XXH_ERROR on failure.
|
1342
|
+
*
|
1343
|
+
* @note Call this to incrementally consume blocks of data.
|
1344
|
+
*
|
1345
|
+
* @see @ref streaming_example "Streaming Example"
|
1205
1346
|
*/
|
1206
1347
|
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length);
|
1207
1348
|
|
1208
1349
|
/*!
|
1209
1350
|
* @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t.
|
1210
1351
|
*
|
1211
|
-
* @note
|
1212
|
-
* Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update,
|
1213
|
-
* digest, and update again.
|
1214
|
-
*
|
1215
1352
|
* @param statePtr The state struct to calculate the hash from.
|
1216
1353
|
*
|
1217
1354
|
* @pre
|
1218
1355
|
* @p statePtr must not be `NULL`.
|
1219
1356
|
*
|
1220
1357
|
* @return The calculated XXH3 64-bit hash value from that state.
|
1358
|
+
*
|
1359
|
+
* @note
|
1360
|
+
* Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update,
|
1361
|
+
* digest, and update again.
|
1362
|
+
*
|
1363
|
+
* @see @ref streaming_example "Streaming Example"
|
1221
1364
|
*/
|
1222
1365
|
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr);
|
1223
1366
|
#endif /* !XXH_NO_STREAM */
|
@@ -1242,26 +1385,71 @@ typedef struct {
|
|
1242
1385
|
} XXH128_hash_t;
|
1243
1386
|
|
1244
1387
|
/*!
|
1245
|
-
* @brief
|
1388
|
+
* @brief Calculates 128-bit unseeded variant of XXH3 of @p data.
|
1389
|
+
*
|
1390
|
+
* @param data The block of data to be hashed, at least @p length bytes in size.
|
1391
|
+
* @param len The length of @p data, in bytes.
|
1392
|
+
*
|
1393
|
+
* @return The calculated 128-bit variant of XXH3 value.
|
1246
1394
|
*
|
1247
1395
|
* The 128-bit variant of XXH3 has more strength, but it has a bit of overhead
|
1248
1396
|
* for shorter inputs.
|
1249
1397
|
*
|
1250
|
-
* This is equivalent to @ref XXH3_128bits_withSeed() with a seed of 0
|
1398
|
+
* This is equivalent to @ref XXH3_128bits_withSeed() with a seed of `0`, however
|
1251
1399
|
* it may have slightly better performance due to constant propagation of the
|
1252
1400
|
* defaults.
|
1253
1401
|
*
|
1254
|
-
* @see
|
1255
|
-
*
|
1256
|
-
* @see
|
1257
|
-
* XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants
|
1258
|
-
* @see
|
1259
|
-
* XXH3_128bits_reset(), XXH3_128bits_update(), XXH3_128bits_digest(): Streaming version.
|
1402
|
+
* @see XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants
|
1403
|
+
* @see @ref single_shot_example "Single Shot Example" for an example.
|
1260
1404
|
*/
|
1261
1405
|
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* data, size_t len);
|
1262
|
-
/*! @brief
|
1406
|
+
/*! @brief Calculates 128-bit seeded variant of XXH3 hash of @p data.
|
1407
|
+
*
|
1408
|
+
* @param data The block of data to be hashed, at least @p length bytes in size.
|
1409
|
+
* @param len The length of @p data, in bytes.
|
1410
|
+
* @param seed The 64-bit seed to alter the hash result predictably.
|
1411
|
+
*
|
1412
|
+
* @return The calculated 128-bit variant of XXH3 value.
|
1413
|
+
*
|
1414
|
+
* @note
|
1415
|
+
* seed == 0 produces the same results as @ref XXH3_64bits().
|
1416
|
+
*
|
1417
|
+
* This variant generates a custom secret on the fly based on default secret
|
1418
|
+
* altered using the @p seed value.
|
1419
|
+
*
|
1420
|
+
* While this operation is decently fast, note that it's not completely free.
|
1421
|
+
*
|
1422
|
+
* @see XXH3_128bits(), XXH3_128bits_withSecret(): other seeding variants
|
1423
|
+
* @see @ref single_shot_example "Single Shot Example" for an example.
|
1424
|
+
*/
|
1263
1425
|
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed);
|
1264
|
-
/*!
|
1426
|
+
/*!
|
1427
|
+
* @brief Calculates 128-bit variant of XXH3 with a custom "secret".
|
1428
|
+
*
|
1429
|
+
* @param data The block of data to be hashed, at least @p len bytes in size.
|
1430
|
+
* @param len The length of @p data, in bytes.
|
1431
|
+
* @param secret The secret data.
|
1432
|
+
* @param secretSize The length of @p secret, in bytes.
|
1433
|
+
*
|
1434
|
+
* @return The calculated 128-bit variant of XXH3 value.
|
1435
|
+
*
|
1436
|
+
* It's possible to provide any blob of bytes as a "secret" to generate the hash.
|
1437
|
+
* This makes it more difficult for an external actor to prepare an intentional collision.
|
1438
|
+
* The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN).
|
1439
|
+
* However, the quality of the secret impacts the dispersion of the hash algorithm.
|
1440
|
+
* Therefore, the secret _must_ look like a bunch of random bytes.
|
1441
|
+
* Avoid "trivial" or structured data such as repeated sequences or a text document.
|
1442
|
+
* Whenever in doubt about the "randomness" of the blob of bytes,
|
1443
|
+
* consider employing @ref XXH3_generateSecret() instead (see below).
|
1444
|
+
* It will generate a proper high entropy secret derived from the blob of bytes.
|
1445
|
+
* Another advantage of using XXH3_generateSecret() is that
|
1446
|
+
* it guarantees that all bits within the initial blob of bytes
|
1447
|
+
* will impact every bit of the output.
|
1448
|
+
* This is not necessarily the case when using the blob of bytes directly
|
1449
|
+
* because, when hashing _small_ inputs, only a portion of the secret is employed.
|
1450
|
+
*
|
1451
|
+
* @see @ref single_shot_example "Single Shot Example" for an example.
|
1452
|
+
*/
|
1265
1453
|
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize);
|
1266
1454
|
|
1267
1455
|
/******* Streaming *******/
|
@@ -1281,36 +1469,65 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE cons
|
|
1281
1469
|
/*!
|
1282
1470
|
* @brief Resets an @ref XXH3_state_t to begin a new hash.
|
1283
1471
|
*
|
1284
|
-
* This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_128bits_update().
|
1285
|
-
* Digest will be equivalent to `XXH3_128bits()`.
|
1286
|
-
*
|
1287
1472
|
* @param statePtr The state struct to reset.
|
1288
1473
|
*
|
1289
1474
|
* @pre
|
1290
1475
|
* @p statePtr must not be `NULL`.
|
1291
1476
|
*
|
1292
|
-
* @return @ref XXH_OK on success
|
1477
|
+
* @return @ref XXH_OK on success.
|
1478
|
+
* @return @ref XXH_ERROR on failure.
|
1479
|
+
*
|
1480
|
+
* @note
|
1481
|
+
* - This function resets `statePtr` and generate a secret with default parameters.
|
1482
|
+
* - Call it before @ref XXH3_128bits_update().
|
1483
|
+
* - Digest will be equivalent to `XXH3_128bits()`.
|
1293
1484
|
*
|
1485
|
+
* @see @ref streaming_example "Streaming Example"
|
1294
1486
|
*/
|
1295
1487
|
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr);
|
1296
1488
|
|
1297
1489
|
/*!
|
1298
1490
|
* @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash.
|
1299
1491
|
*
|
1300
|
-
*
|
1301
|
-
*
|
1492
|
+
* @param statePtr The state struct to reset.
|
1493
|
+
* @param seed The 64-bit seed to alter the hash result predictably.
|
1494
|
+
*
|
1495
|
+
* @pre
|
1496
|
+
* @p statePtr must not be `NULL`.
|
1497
|
+
*
|
1498
|
+
* @return @ref XXH_OK on success.
|
1499
|
+
* @return @ref XXH_ERROR on failure.
|
1500
|
+
*
|
1501
|
+
* @note
|
1502
|
+
* - This function resets `statePtr` and generate a secret from `seed`.
|
1503
|
+
* - Call it before @ref XXH3_128bits_update().
|
1504
|
+
* - Digest will be equivalent to `XXH3_128bits_withSeed()`.
|
1505
|
+
*
|
1506
|
+
* @see @ref streaming_example "Streaming Example"
|
1507
|
+
*/
|
1508
|
+
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed);
|
1509
|
+
/*!
|
1510
|
+
* @brief Resets an @ref XXH3_state_t with secret data to begin a new hash.
|
1302
1511
|
*
|
1303
|
-
* @param statePtr
|
1304
|
-
* @param
|
1512
|
+
* @param statePtr The state struct to reset.
|
1513
|
+
* @param secret The secret data.
|
1514
|
+
* @param secretSize The length of @p secret, in bytes.
|
1305
1515
|
*
|
1306
1516
|
* @pre
|
1307
1517
|
* @p statePtr must not be `NULL`.
|
1308
1518
|
*
|
1309
|
-
* @return @ref XXH_OK on success
|
1519
|
+
* @return @ref XXH_OK on success.
|
1520
|
+
* @return @ref XXH_ERROR on failure.
|
1521
|
+
*
|
1522
|
+
* `secret` is referenced, it _must outlive_ the hash streaming session.
|
1523
|
+
* Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN,
|
1524
|
+
* and the quality of produced hash values depends on secret's entropy
|
1525
|
+
* (secret's content should look like a bunch of random bytes).
|
1526
|
+
* When in doubt about the randomness of a candidate `secret`,
|
1527
|
+
* consider employing `XXH3_generateSecret()` instead (see below).
|
1310
1528
|
*
|
1529
|
+
* @see @ref streaming_example "Streaming Example"
|
1311
1530
|
*/
|
1312
|
-
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed);
|
1313
|
-
/*! @brief Custom secret 128-bit variant of XXH3. @see XXH_64bits_reset_withSecret(). */
|
1314
1531
|
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize);
|
1315
1532
|
|
1316
1533
|
/*!
|
@@ -1324,28 +1541,32 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_sta
|
|
1324
1541
|
*
|
1325
1542
|
* @pre
|
1326
1543
|
* @p statePtr must not be `NULL`.
|
1327
|
-
*
|
1544
|
+
*
|
1545
|
+
* @return @ref XXH_OK on success.
|
1546
|
+
* @return @ref XXH_ERROR on failure.
|
1547
|
+
*
|
1548
|
+
* @note
|
1328
1549
|
* The memory between @p input and @p input + @p length must be valid,
|
1329
1550
|
* readable, contiguous memory. However, if @p length is `0`, @p input may be
|
1330
1551
|
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
1331
1552
|
*
|
1332
|
-
* @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
|
1333
1553
|
*/
|
1334
1554
|
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length);
|
1335
1555
|
|
1336
1556
|
/*!
|
1337
1557
|
* @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t.
|
1338
1558
|
*
|
1339
|
-
* @note
|
1340
|
-
* Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update,
|
1341
|
-
* digest, and update again.
|
1342
|
-
*
|
1343
1559
|
* @param statePtr The state struct to calculate the hash from.
|
1344
1560
|
*
|
1345
1561
|
* @pre
|
1346
1562
|
* @p statePtr must not be `NULL`.
|
1347
1563
|
*
|
1348
1564
|
* @return The calculated XXH3 128-bit hash value from that state.
|
1565
|
+
*
|
1566
|
+
* @note
|
1567
|
+
* Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update,
|
1568
|
+
* digest, and update again.
|
1569
|
+
*
|
1349
1570
|
*/
|
1350
1571
|
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr);
|
1351
1572
|
#endif /* !XXH_NO_STREAM */
|
@@ -1355,18 +1576,27 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const X
|
|
1355
1576
|
* Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */
|
1356
1577
|
|
1357
1578
|
/*!
|
1358
|
-
*
|
1359
|
-
*
|
1579
|
+
* @brief Check equality of two XXH128_hash_t values
|
1580
|
+
*
|
1581
|
+
* @param h1 The 128-bit hash value.
|
1582
|
+
* @param h2 Another 128-bit hash value.
|
1583
|
+
*
|
1584
|
+
* @return `1` if `h1` and `h2` are equal.
|
1585
|
+
* @return `0` if they are not.
|
1360
1586
|
*/
|
1361
1587
|
XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2);
|
1362
1588
|
|
1363
1589
|
/*!
|
1364
1590
|
* @brief Compares two @ref XXH128_hash_t
|
1591
|
+
*
|
1365
1592
|
* This comparator is compatible with stdlib's `qsort()`/`bsearch()`.
|
1366
1593
|
*
|
1367
|
-
* @
|
1368
|
-
*
|
1369
|
-
*
|
1594
|
+
* @param h128_1 Left-hand side value
|
1595
|
+
* @param h128_2 Right-hand side value
|
1596
|
+
*
|
1597
|
+
* @return >0 if @p h128_1 > @p h128_2
|
1598
|
+
* @return =0 if @p h128_1 == @p h128_2
|
1599
|
+
* @return <0 if @p h128_1 < @p h128_2
|
1370
1600
|
*/
|
1371
1601
|
XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2);
|
1372
1602
|
|
@@ -1378,11 +1608,12 @@ typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical
|
|
1378
1608
|
/*!
|
1379
1609
|
* @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t.
|
1380
1610
|
*
|
1381
|
-
* @param dst
|
1611
|
+
* @param dst The @ref XXH128_canonical_t pointer to be stored to.
|
1382
1612
|
* @param hash The @ref XXH128_hash_t to be converted.
|
1383
1613
|
*
|
1384
1614
|
* @pre
|
1385
1615
|
* @p dst must not be `NULL`.
|
1616
|
+
* @see @ref canonical_representation_example "Canonical Representation Example"
|
1386
1617
|
*/
|
1387
1618
|
XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash);
|
1388
1619
|
|
@@ -1395,6 +1626,7 @@ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* ds
|
|
1395
1626
|
* @p src must not be `NULL`.
|
1396
1627
|
*
|
1397
1628
|
* @return The converted hash.
|
1629
|
+
* @see @ref canonical_representation_example "Canonical Representation Example"
|
1398
1630
|
*/
|
1399
1631
|
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src);
|
1400
1632
|
|
@@ -1440,9 +1672,9 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE con
|
|
1440
1672
|
struct XXH32_state_s {
|
1441
1673
|
XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */
|
1442
1674
|
XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */
|
1443
|
-
XXH32_hash_t
|
1444
|
-
|
1445
|
-
XXH32_hash_t
|
1675
|
+
XXH32_hash_t acc[4]; /*!< Accumulator lanes */
|
1676
|
+
unsigned char buffer[16]; /*!< Internal buffer for partial reads. */
|
1677
|
+
XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */
|
1446
1678
|
XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */
|
1447
1679
|
}; /* typedef'd to XXH32_state_t */
|
1448
1680
|
|
@@ -1463,9 +1695,9 @@ struct XXH32_state_s {
|
|
1463
1695
|
*/
|
1464
1696
|
struct XXH64_state_s {
|
1465
1697
|
XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */
|
1466
|
-
XXH64_hash_t
|
1467
|
-
|
1468
|
-
XXH32_hash_t
|
1698
|
+
XXH64_hash_t acc[4]; /*!< Accumulator lanes */
|
1699
|
+
unsigned char buffer[32]; /*!< Internal buffer for partial reads.. */
|
1700
|
+
XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */
|
1469
1701
|
XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/
|
1470
1702
|
XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */
|
1471
1703
|
}; /* typedef'd to XXH64_state_t */
|
@@ -1473,8 +1705,7 @@ struct XXH64_state_s {
|
|
1473
1705
|
#ifndef XXH_NO_XXH3
|
1474
1706
|
|
1475
1707
|
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */
|
1476
|
-
#
|
1477
|
-
# define XXH_ALIGN(n) alignas(n)
|
1708
|
+
# define XXH_ALIGN(n) _Alignas(n)
|
1478
1709
|
#elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */
|
1479
1710
|
/* In C++ alignas() is a keyword */
|
1480
1711
|
# define XXH_ALIGN(n) alignas(n)
|
@@ -1587,7 +1818,20 @@ struct XXH3_state_s {
|
|
1587
1818
|
|
1588
1819
|
|
1589
1820
|
/*!
|
1590
|
-
*
|
1821
|
+
* @brief Calculates the 128-bit hash of @p data using XXH3.
|
1822
|
+
*
|
1823
|
+
* @param data The block of data to be hashed, at least @p len bytes in size.
|
1824
|
+
* @param len The length of @p data, in bytes.
|
1825
|
+
* @param seed The 64-bit seed to alter the hash's output predictably.
|
1826
|
+
*
|
1827
|
+
* @pre
|
1828
|
+
* The memory between @p data and @p data + @p len must be valid,
|
1829
|
+
* readable, contiguous memory. However, if @p len is `0`, @p data may be
|
1830
|
+
* `NULL`. In C++, this also must be *TriviallyCopyable*.
|
1831
|
+
*
|
1832
|
+
* @return The calculated 128-bit XXH3 value.
|
1833
|
+
*
|
1834
|
+
* @see @ref single_shot_example "Single Shot Example" for an example.
|
1591
1835
|
*/
|
1592
1836
|
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed);
|
1593
1837
|
|
@@ -1596,9 +1840,16 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, siz
|
|
1596
1840
|
/* Symbols defined below must be considered tied to a specific library version. */
|
1597
1841
|
|
1598
1842
|
/*!
|
1599
|
-
*
|
1843
|
+
* @brief Derive a high-entropy secret from any user-defined content, named customSeed.
|
1844
|
+
*
|
1845
|
+
* @param secretBuffer A writable buffer for derived high-entropy secret data.
|
1846
|
+
* @param secretSize Size of secretBuffer, in bytes. Must be >= XXH3_SECRET_SIZE_MIN.
|
1847
|
+
* @param customSeed A user-defined content.
|
1848
|
+
* @param customSeedSize Size of customSeed, in bytes.
|
1849
|
+
*
|
1850
|
+
* @return @ref XXH_OK on success.
|
1851
|
+
* @return @ref XXH_ERROR on failure.
|
1600
1852
|
*
|
1601
|
-
* Derive a high-entropy secret from any user-defined content, named customSeed.
|
1602
1853
|
* The generated secret can be used in combination with `*_withSecret()` functions.
|
1603
1854
|
* The `_withSecret()` variants are useful to provide a higher level of protection
|
1604
1855
|
* than 64-bit seed, as it becomes much more difficult for an external actor to
|
@@ -1651,6 +1902,9 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer
|
|
1651
1902
|
/*!
|
1652
1903
|
* @brief Generate the same secret as the _withSeed() variants.
|
1653
1904
|
*
|
1905
|
+
* @param secretBuffer A writable buffer of @ref XXH3_SECRET_DEFAULT_SIZE bytes
|
1906
|
+
* @param seed The 64-bit seed to alter the hash result predictably.
|
1907
|
+
*
|
1654
1908
|
* The generated secret can be used in combination with
|
1655
1909
|
*`*_withSecret()` and `_withSecretandSeed()` variants.
|
1656
1910
|
*
|
@@ -1670,7 +1924,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer
|
|
1670
1924
|
* };
|
1671
1925
|
* // Fast, caches the seeded secret for future uses.
|
1672
1926
|
* class HashFast {
|
1673
|
-
* unsigned char secret[
|
1927
|
+
* unsigned char secret[XXH3_SECRET_DEFAULT_SIZE];
|
1674
1928
|
* public:
|
1675
1929
|
* HashFast(XXH64_hash_t s) {
|
1676
1930
|
* XXH3_generateSecret_fromSeed(secret, seed);
|
@@ -1682,15 +1936,26 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer
|
|
1682
1936
|
* }
|
1683
1937
|
* };
|
1684
1938
|
* @endcode
|
1685
|
-
* @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes
|
1686
|
-
* @param seed The seed to seed the state.
|
1687
1939
|
*/
|
1688
1940
|
XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed);
|
1689
1941
|
|
1690
1942
|
/*!
|
1691
|
-
*
|
1692
|
-
|
1693
|
-
|
1943
|
+
* @brief Maximum size of "short" key in bytes.
|
1944
|
+
*/
|
1945
|
+
#define XXH3_MIDSIZE_MAX 240
|
1946
|
+
|
1947
|
+
/*!
|
1948
|
+
* @brief Calculates 64/128-bit seeded variant of XXH3 hash of @p data.
|
1949
|
+
*
|
1950
|
+
* @param data The block of data to be hashed, at least @p len bytes in size.
|
1951
|
+
* @param len The length of @p data, in bytes.
|
1952
|
+
* @param secret The secret data.
|
1953
|
+
* @param secretSize The length of @p secret, in bytes.
|
1954
|
+
* @param seed The 64-bit seed to alter the hash result predictably.
|
1955
|
+
*
|
1956
|
+
* These variants generate hash values using either:
|
1957
|
+
* - @p seed for "short" keys (< @ref XXH3_MIDSIZE_MAX = 240 bytes)
|
1958
|
+
* - @p secret for "large" keys (>= @ref XXH3_MIDSIZE_MAX).
|
1694
1959
|
*
|
1695
1960
|
* This generally benefits speed, compared to `_withSeed()` or `_withSecret()`.
|
1696
1961
|
* `_withSeed()` has to generate the secret on the fly for "large" keys.
|
@@ -1717,22 +1982,71 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t
|
|
1717
1982
|
XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* data, size_t len,
|
1718
1983
|
XXH_NOESCAPE const void* secret, size_t secretSize,
|
1719
1984
|
XXH64_hash_t seed);
|
1720
|
-
|
1985
|
+
|
1986
|
+
/*!
|
1987
|
+
* @brief Calculates 128-bit seeded variant of XXH3 hash of @p data.
|
1988
|
+
*
|
1989
|
+
* @param data The memory segment to be hashed, at least @p len bytes in size.
|
1990
|
+
* @param length The length of @p data, in bytes.
|
1991
|
+
* @param secret The secret used to alter hash result predictably.
|
1992
|
+
* @param secretSize The length of @p secret, in bytes (must be >= XXH3_SECRET_SIZE_MIN)
|
1993
|
+
* @param seed64 The 64-bit seed to alter the hash result predictably.
|
1994
|
+
*
|
1995
|
+
* @return @ref XXH_OK on success.
|
1996
|
+
* @return @ref XXH_ERROR on failure.
|
1997
|
+
*
|
1998
|
+
* @see XXH3_64bits_withSecretandSeed(): contract is the same.
|
1999
|
+
*/
|
1721
2000
|
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t
|
1722
2001
|
XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length,
|
1723
2002
|
XXH_NOESCAPE const void* secret, size_t secretSize,
|
1724
2003
|
XXH64_hash_t seed64);
|
2004
|
+
|
1725
2005
|
#ifndef XXH_NO_STREAM
|
1726
|
-
/*!
|
2006
|
+
/*!
|
2007
|
+
* @brief Resets an @ref XXH3_state_t with secret data to begin a new hash.
|
2008
|
+
*
|
2009
|
+
* @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState().
|
2010
|
+
* @param secret The secret data.
|
2011
|
+
* @param secretSize The length of @p secret, in bytes.
|
2012
|
+
* @param seed64 The 64-bit seed to alter the hash result predictably.
|
2013
|
+
*
|
2014
|
+
* @return @ref XXH_OK on success.
|
2015
|
+
* @return @ref XXH_ERROR on failure.
|
2016
|
+
*
|
2017
|
+
* @see XXH3_64bits_withSecretandSeed(). Contract is identical.
|
2018
|
+
*/
|
1727
2019
|
XXH_PUBLIC_API XXH_errorcode
|
1728
2020
|
XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr,
|
1729
2021
|
XXH_NOESCAPE const void* secret, size_t secretSize,
|
1730
2022
|
XXH64_hash_t seed64);
|
1731
|
-
|
2023
|
+
|
2024
|
+
/*!
|
2025
|
+
* @brief Resets an @ref XXH3_state_t with secret data to begin a new hash.
|
2026
|
+
*
|
2027
|
+
* @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState().
|
2028
|
+
* @param secret The secret data.
|
2029
|
+
* @param secretSize The length of @p secret, in bytes.
|
2030
|
+
* @param seed64 The 64-bit seed to alter the hash result predictably.
|
2031
|
+
*
|
2032
|
+
* @return @ref XXH_OK on success.
|
2033
|
+
* @return @ref XXH_ERROR on failure.
|
2034
|
+
*
|
2035
|
+
* @see XXH3_64bits_withSecretandSeed(). Contract is identical.
|
2036
|
+
*
|
2037
|
+
* Note: there was a bug in an earlier version of this function (<= v0.8.2)
|
2038
|
+
* that would make it generate an incorrect hash value
|
2039
|
+
* when @p seed == 0 and @p length < XXH3_MIDSIZE_MAX
|
2040
|
+
* and @p secret is different from XXH3_generateSecret_fromSeed().
|
2041
|
+
* As stated in the contract, the correct hash result must be
|
2042
|
+
* the same as XXH3_128bits_withSeed() when @p length <= XXH3_MIDSIZE_MAX.
|
2043
|
+
* Results generated by this older version are wrong, hence not comparable.
|
2044
|
+
*/
|
1732
2045
|
XXH_PUBLIC_API XXH_errorcode
|
1733
2046
|
XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr,
|
1734
2047
|
XXH_NOESCAPE const void* secret, size_t secretSize,
|
1735
2048
|
XXH64_hash_t seed64);
|
2049
|
+
|
1736
2050
|
#endif /* !XXH_NO_STREAM */
|
1737
2051
|
|
1738
2052
|
#endif /* !XXH_NO_XXH3 */
|
@@ -2100,15 +2414,15 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
|
|
2100
2414
|
|
2101
2415
|
#if XXH_NO_INLINE_HINTS /* disable inlining hints */
|
2102
2416
|
# if defined(__GNUC__) || defined(__clang__)
|
2103
|
-
# define XXH_FORCE_INLINE static __attribute__((
|
2417
|
+
# define XXH_FORCE_INLINE static __attribute__((__unused__))
|
2104
2418
|
# else
|
2105
2419
|
# define XXH_FORCE_INLINE static
|
2106
2420
|
# endif
|
2107
2421
|
# define XXH_NO_INLINE static
|
2108
2422
|
/* enable inlining hints */
|
2109
2423
|
#elif defined(__GNUC__) || defined(__clang__)
|
2110
|
-
# define XXH_FORCE_INLINE static __inline__ __attribute__((
|
2111
|
-
# define XXH_NO_INLINE static __attribute__((
|
2424
|
+
# define XXH_FORCE_INLINE static __inline__ __attribute__((__always_inline__, __unused__))
|
2425
|
+
# define XXH_NO_INLINE static __attribute__((__noinline__))
|
2112
2426
|
#elif defined(_MSC_VER) /* Visual Studio */
|
2113
2427
|
# define XXH_FORCE_INLINE static __forceinline
|
2114
2428
|
# define XXH_NO_INLINE static __declspec(noinline)
|
@@ -2121,12 +2435,34 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
|
|
2121
2435
|
# define XXH_NO_INLINE static
|
2122
2436
|
#endif
|
2123
2437
|
|
2438
|
+
#if defined(XXH_INLINE_ALL)
|
2439
|
+
# define XXH_STATIC XXH_FORCE_INLINE
|
2440
|
+
#else
|
2441
|
+
# define XXH_STATIC static
|
2442
|
+
#endif
|
2443
|
+
|
2124
2444
|
#if XXH3_INLINE_SECRET
|
2125
2445
|
# define XXH3_WITH_SECRET_INLINE XXH_FORCE_INLINE
|
2126
2446
|
#else
|
2127
2447
|
# define XXH3_WITH_SECRET_INLINE XXH_NO_INLINE
|
2128
2448
|
#endif
|
2129
2449
|
|
2450
|
+
#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */
|
2451
|
+
# define XXH_RESTRICT /* disable */
|
2452
|
+
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */
|
2453
|
+
# define XXH_RESTRICT restrict
|
2454
|
+
#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \
|
2455
|
+
|| (defined (__clang__)) \
|
2456
|
+
|| (defined (_MSC_VER) && (_MSC_VER >= 1400)) \
|
2457
|
+
|| (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300))
|
2458
|
+
/*
|
2459
|
+
* There are a LOT more compilers that recognize __restrict but this
|
2460
|
+
* covers the major ones.
|
2461
|
+
*/
|
2462
|
+
# define XXH_RESTRICT __restrict
|
2463
|
+
#else
|
2464
|
+
# define XXH_RESTRICT /* disable */
|
2465
|
+
#endif
|
2130
2466
|
|
2131
2467
|
/* *************************************
|
2132
2468
|
* Debug
|
@@ -2206,10 +2542,14 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
|
|
2206
2542
|
#if !defined (__VMS) \
|
2207
2543
|
&& (defined (__cplusplus) \
|
2208
2544
|
|| (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
|
2209
|
-
#
|
2210
|
-
|
2545
|
+
# ifdef _AIX
|
2546
|
+
# include <inttypes.h>
|
2547
|
+
# else
|
2548
|
+
# include <stdint.h>
|
2549
|
+
# endif
|
2550
|
+
typedef uint8_t xxh_u8;
|
2211
2551
|
#else
|
2212
|
-
|
2552
|
+
typedef unsigned char xxh_u8;
|
2213
2553
|
#endif
|
2214
2554
|
typedef XXH32_hash_t xxh_u32;
|
2215
2555
|
|
@@ -2295,11 +2635,11 @@ static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr;
|
|
2295
2635
|
* https://gcc.godbolt.org/z/xYez1j67Y.
|
2296
2636
|
*/
|
2297
2637
|
#ifdef XXH_OLD_NAMES
|
2298
|
-
typedef union { xxh_u32 u32; } __attribute__((
|
2638
|
+
typedef union { xxh_u32 u32; } __attribute__((__packed__)) unalign;
|
2299
2639
|
#endif
|
2300
2640
|
static xxh_u32 XXH_read32(const void* ptr)
|
2301
2641
|
{
|
2302
|
-
typedef __attribute__((
|
2642
|
+
typedef __attribute__((__aligned__(1))) xxh_u32 xxh_unalign32;
|
2303
2643
|
return *((const xxh_unalign32*)ptr);
|
2304
2644
|
}
|
2305
2645
|
|
@@ -2445,6 +2785,9 @@ static int XXH_isLittleEndian(void)
|
|
2445
2785
|
&& XXH_HAS_BUILTIN(__builtin_rotateleft64)
|
2446
2786
|
# define XXH_rotl32 __builtin_rotateleft32
|
2447
2787
|
# define XXH_rotl64 __builtin_rotateleft64
|
2788
|
+
#elif XXH_HAS_BUILTIN(__builtin_stdc_rotate_left)
|
2789
|
+
# define XXH_rotl32 __builtin_stdc_rotate_left
|
2790
|
+
# define XXH_rotl64 __builtin_stdc_rotate_left
|
2448
2791
|
/* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */
|
2449
2792
|
#elif defined(_MSC_VER)
|
2450
2793
|
# define XXH_rotl32(x,r) _rotl(x,r)
|
@@ -2590,7 +2933,7 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
|
|
2590
2933
|
#if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
|
2591
2934
|
/*
|
2592
2935
|
* UGLY HACK:
|
2593
|
-
* A compiler fence is
|
2936
|
+
* A compiler fence is used to prevent GCC and Clang from
|
2594
2937
|
* autovectorizing the XXH32 loop (pragmas and attributes don't work for some
|
2595
2938
|
* reason) without globally disabling SSE4.1.
|
2596
2939
|
*
|
@@ -2651,6 +2994,61 @@ static xxh_u32 XXH32_avalanche(xxh_u32 hash)
|
|
2651
2994
|
|
2652
2995
|
#define XXH_get32bits(p) XXH_readLE32_align(p, align)
|
2653
2996
|
|
2997
|
+
/*!
|
2998
|
+
* @internal
|
2999
|
+
* @brief Sets up the initial accumulator state for XXH32().
|
3000
|
+
*/
|
3001
|
+
XXH_FORCE_INLINE void
|
3002
|
+
XXH32_initAccs(xxh_u32 *acc, xxh_u32 seed)
|
3003
|
+
{
|
3004
|
+
XXH_ASSERT(acc != NULL);
|
3005
|
+
acc[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
|
3006
|
+
acc[1] = seed + XXH_PRIME32_2;
|
3007
|
+
acc[2] = seed + 0;
|
3008
|
+
acc[3] = seed - XXH_PRIME32_1;
|
3009
|
+
}
|
3010
|
+
|
3011
|
+
/*!
|
3012
|
+
* @internal
|
3013
|
+
* @brief Consumes a block of data for XXH32().
|
3014
|
+
*
|
3015
|
+
* @return the end input pointer.
|
3016
|
+
*/
|
3017
|
+
XXH_FORCE_INLINE const xxh_u8 *
|
3018
|
+
XXH32_consumeLong(
|
3019
|
+
xxh_u32 *XXH_RESTRICT acc,
|
3020
|
+
xxh_u8 const *XXH_RESTRICT input,
|
3021
|
+
size_t len,
|
3022
|
+
XXH_alignment align
|
3023
|
+
)
|
3024
|
+
{
|
3025
|
+
const xxh_u8* const bEnd = input + len;
|
3026
|
+
const xxh_u8* const limit = bEnd - 15;
|
3027
|
+
XXH_ASSERT(acc != NULL);
|
3028
|
+
XXH_ASSERT(input != NULL);
|
3029
|
+
XXH_ASSERT(len >= 16);
|
3030
|
+
do {
|
3031
|
+
acc[0] = XXH32_round(acc[0], XXH_get32bits(input)); input += 4;
|
3032
|
+
acc[1] = XXH32_round(acc[1], XXH_get32bits(input)); input += 4;
|
3033
|
+
acc[2] = XXH32_round(acc[2], XXH_get32bits(input)); input += 4;
|
3034
|
+
acc[3] = XXH32_round(acc[3], XXH_get32bits(input)); input += 4;
|
3035
|
+
} while (input < limit);
|
3036
|
+
|
3037
|
+
return input;
|
3038
|
+
}
|
3039
|
+
|
3040
|
+
/*!
|
3041
|
+
* @internal
|
3042
|
+
* @brief Merges the accumulator lanes together for XXH32()
|
3043
|
+
*/
|
3044
|
+
XXH_FORCE_INLINE XXH_PUREF xxh_u32
|
3045
|
+
XXH32_mergeAccs(const xxh_u32 *acc)
|
3046
|
+
{
|
3047
|
+
XXH_ASSERT(acc != NULL);
|
3048
|
+
return XXH_rotl32(acc[0], 1) + XXH_rotl32(acc[1], 7)
|
3049
|
+
+ XXH_rotl32(acc[2], 12) + XXH_rotl32(acc[3], 18);
|
3050
|
+
}
|
3051
|
+
|
2654
3052
|
/*!
|
2655
3053
|
* @internal
|
2656
3054
|
* @brief Processes the last 0-15 bytes of @p ptr.
|
@@ -2763,22 +3161,12 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment
|
|
2763
3161
|
if (input==NULL) XXH_ASSERT(len == 0);
|
2764
3162
|
|
2765
3163
|
if (len>=16) {
|
2766
|
-
|
2767
|
-
|
2768
|
-
xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
|
2769
|
-
xxh_u32 v2 = seed + XXH_PRIME32_2;
|
2770
|
-
xxh_u32 v3 = seed + 0;
|
2771
|
-
xxh_u32 v4 = seed - XXH_PRIME32_1;
|
3164
|
+
xxh_u32 acc[4];
|
3165
|
+
XXH32_initAccs(acc, seed);
|
2772
3166
|
|
2773
|
-
|
2774
|
-
|
2775
|
-
|
2776
|
-
v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4;
|
2777
|
-
v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4;
|
2778
|
-
} while (input < limit);
|
2779
|
-
|
2780
|
-
h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7)
|
2781
|
-
+ XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
|
3167
|
+
input = XXH32_consumeLong(acc, input, len, align);
|
3168
|
+
|
3169
|
+
h32 = XXH32_mergeAccs(acc);
|
2782
3170
|
} else {
|
2783
3171
|
h32 = seed + XXH_PRIME32_5;
|
2784
3172
|
}
|
@@ -2834,10 +3222,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s
|
|
2834
3222
|
{
|
2835
3223
|
XXH_ASSERT(statePtr != NULL);
|
2836
3224
|
memset(statePtr, 0, sizeof(*statePtr));
|
2837
|
-
statePtr->
|
2838
|
-
statePtr->v[1] = seed + XXH_PRIME32_2;
|
2839
|
-
statePtr->v[2] = seed + 0;
|
2840
|
-
statePtr->v[3] = seed - XXH_PRIME32_1;
|
3225
|
+
XXH32_initAccs(statePtr->acc, seed);
|
2841
3226
|
return XXH_OK;
|
2842
3227
|
}
|
2843
3228
|
|
@@ -2851,45 +3236,37 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len)
|
|
2851
3236
|
return XXH_OK;
|
2852
3237
|
}
|
2853
3238
|
|
2854
|
-
|
2855
|
-
|
3239
|
+
state->total_len_32 += (XXH32_hash_t)len;
|
3240
|
+
state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16));
|
2856
3241
|
|
2857
|
-
|
2858
|
-
|
3242
|
+
XXH_ASSERT(state->bufferedSize < sizeof(state->buffer));
|
3243
|
+
if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */
|
3244
|
+
XXH_memcpy(state->buffer + state->bufferedSize, input, len);
|
3245
|
+
state->bufferedSize += (XXH32_hash_t)len;
|
3246
|
+
return XXH_OK;
|
3247
|
+
}
|
2859
3248
|
|
2860
|
-
|
2861
|
-
|
2862
|
-
state->memsize += (XXH32_hash_t)len;
|
2863
|
-
return XXH_OK;
|
2864
|
-
}
|
3249
|
+
{ const xxh_u8* xinput = (const xxh_u8*)input;
|
3250
|
+
const xxh_u8* const bEnd = xinput + len;
|
2865
3251
|
|
2866
|
-
if (state->
|
2867
|
-
XXH_memcpy(
|
2868
|
-
|
2869
|
-
|
2870
|
-
|
2871
|
-
|
2872
|
-
state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32));
|
2873
|
-
}
|
2874
|
-
p += 16-state->memsize;
|
2875
|
-
state->memsize = 0;
|
3252
|
+
if (state->bufferedSize) { /* non-empty buffer: complete first */
|
3253
|
+
XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize);
|
3254
|
+
xinput += sizeof(state->buffer) - state->bufferedSize;
|
3255
|
+
/* then process one round */
|
3256
|
+
(void)XXH32_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned);
|
3257
|
+
state->bufferedSize = 0;
|
2876
3258
|
}
|
2877
3259
|
|
2878
|
-
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4;
|
2883
|
-
state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4;
|
2884
|
-
state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4;
|
2885
|
-
state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4;
|
2886
|
-
} while (p<=limit);
|
2887
|
-
|
3260
|
+
XXH_ASSERT(xinput <= bEnd);
|
3261
|
+
if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) {
|
3262
|
+
/* Process the remaining data */
|
3263
|
+
xinput = XXH32_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned);
|
2888
3264
|
}
|
2889
3265
|
|
2890
|
-
if (
|
2891
|
-
|
2892
|
-
state->
|
3266
|
+
if (xinput < bEnd) {
|
3267
|
+
/* Copy the leftover to the tmp buffer */
|
3268
|
+
XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput));
|
3269
|
+
state->bufferedSize = (unsigned)(bEnd-xinput);
|
2893
3270
|
}
|
2894
3271
|
}
|
2895
3272
|
|
@@ -2903,36 +3280,20 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
|
|
2903
3280
|
xxh_u32 h32;
|
2904
3281
|
|
2905
3282
|
if (state->large_len) {
|
2906
|
-
h32 =
|
2907
|
-
+ XXH_rotl32(state->v[1], 7)
|
2908
|
-
+ XXH_rotl32(state->v[2], 12)
|
2909
|
-
+ XXH_rotl32(state->v[3], 18);
|
3283
|
+
h32 = XXH32_mergeAccs(state->acc);
|
2910
3284
|
} else {
|
2911
|
-
h32 = state->
|
3285
|
+
h32 = state->acc[2] /* == seed */ + XXH_PRIME32_5;
|
2912
3286
|
}
|
2913
3287
|
|
2914
3288
|
h32 += state->total_len_32;
|
2915
3289
|
|
2916
|
-
return XXH32_finalize(h32,
|
3290
|
+
return XXH32_finalize(h32, state->buffer, state->bufferedSize, XXH_aligned);
|
2917
3291
|
}
|
2918
3292
|
#endif /* !XXH_NO_STREAM */
|
2919
3293
|
|
2920
3294
|
/******* Canonical representation *******/
|
2921
3295
|
|
2922
|
-
/*!
|
2923
|
-
* @ingroup XXH32_family
|
2924
|
-
* The default return values from XXH functions are unsigned 32 and 64 bit
|
2925
|
-
* integers.
|
2926
|
-
*
|
2927
|
-
* The canonical representation uses big endian convention, the same convention
|
2928
|
-
* as human-readable numbers (large digits first).
|
2929
|
-
*
|
2930
|
-
* This way, hash values can be written into a file or buffer, remaining
|
2931
|
-
* comparable across different systems.
|
2932
|
-
*
|
2933
|
-
* The following functions allow transformation of hash values to and from their
|
2934
|
-
* canonical format.
|
2935
|
-
*/
|
3296
|
+
/*! @ingroup XXH32_family */
|
2936
3297
|
XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
|
2937
3298
|
{
|
2938
3299
|
XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
|
@@ -2987,11 +3348,11 @@ static xxh_u64 XXH_read64(const void* memPtr)
|
|
2987
3348
|
* https://gcc.godbolt.org/z/xYez1j67Y.
|
2988
3349
|
*/
|
2989
3350
|
#ifdef XXH_OLD_NAMES
|
2990
|
-
typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((
|
3351
|
+
typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((__packed__)) unalign64;
|
2991
3352
|
#endif
|
2992
3353
|
static xxh_u64 XXH_read64(const void* ptr)
|
2993
3354
|
{
|
2994
|
-
typedef __attribute__((
|
3355
|
+
typedef __attribute__((__aligned__(1))) xxh_u64 xxh_unalign64;
|
2995
3356
|
return *((const xxh_unalign64*)ptr);
|
2996
3357
|
}
|
2997
3358
|
|
@@ -3110,6 +3471,23 @@ static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input)
|
|
3110
3471
|
acc += input * XXH_PRIME64_2;
|
3111
3472
|
acc = XXH_rotl64(acc, 31);
|
3112
3473
|
acc *= XXH_PRIME64_1;
|
3474
|
+
#if (defined(__AVX512F__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
|
3475
|
+
/*
|
3476
|
+
* DISABLE AUTOVECTORIZATION:
|
3477
|
+
* A compiler fence is used to prevent GCC and Clang from
|
3478
|
+
* autovectorizing the XXH64 loop (pragmas and attributes don't work for some
|
3479
|
+
* reason) without globally disabling AVX512.
|
3480
|
+
*
|
3481
|
+
* Autovectorization of XXH64 tends to be detrimental,
|
3482
|
+
* though the exact outcome may change depending on exact cpu and compiler version.
|
3483
|
+
* For information, it has been reported as detrimental for Skylake-X,
|
3484
|
+
* but possibly beneficial for Zen4.
|
3485
|
+
*
|
3486
|
+
* The default is to disable auto-vectorization,
|
3487
|
+
* but you can select to enable it instead using `XXH_ENABLE_AUTOVECTORIZE` build variable.
|
3488
|
+
*/
|
3489
|
+
XXH_COMPILER_GUARD(acc);
|
3490
|
+
#endif
|
3113
3491
|
return acc;
|
3114
3492
|
}
|
3115
3493
|
|
@@ -3135,6 +3513,85 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash)
|
|
3135
3513
|
|
3136
3514
|
#define XXH_get64bits(p) XXH_readLE64_align(p, align)
|
3137
3515
|
|
3516
|
+
/*!
|
3517
|
+
* @internal
|
3518
|
+
* @brief Sets up the initial accumulator state for XXH64().
|
3519
|
+
*/
|
3520
|
+
XXH_FORCE_INLINE void
|
3521
|
+
XXH64_initAccs(xxh_u64 *acc, xxh_u64 seed)
|
3522
|
+
{
|
3523
|
+
XXH_ASSERT(acc != NULL);
|
3524
|
+
acc[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
|
3525
|
+
acc[1] = seed + XXH_PRIME64_2;
|
3526
|
+
acc[2] = seed + 0;
|
3527
|
+
acc[3] = seed - XXH_PRIME64_1;
|
3528
|
+
}
|
3529
|
+
|
3530
|
+
/*!
|
3531
|
+
* @internal
|
3532
|
+
* @brief Consumes a block of data for XXH64().
|
3533
|
+
*
|
3534
|
+
* @return the end input pointer.
|
3535
|
+
*/
|
3536
|
+
XXH_FORCE_INLINE const xxh_u8 *
|
3537
|
+
XXH64_consumeLong(
|
3538
|
+
xxh_u64 *XXH_RESTRICT acc,
|
3539
|
+
xxh_u8 const *XXH_RESTRICT input,
|
3540
|
+
size_t len,
|
3541
|
+
XXH_alignment align
|
3542
|
+
)
|
3543
|
+
{
|
3544
|
+
const xxh_u8* const bEnd = input + len;
|
3545
|
+
const xxh_u8* const limit = bEnd - 31;
|
3546
|
+
XXH_ASSERT(acc != NULL);
|
3547
|
+
XXH_ASSERT(input != NULL);
|
3548
|
+
XXH_ASSERT(len >= 32);
|
3549
|
+
do {
|
3550
|
+
/* reroll on 32-bit */
|
3551
|
+
if (sizeof(void *) < sizeof(xxh_u64)) {
|
3552
|
+
size_t i;
|
3553
|
+
for (i = 0; i < 4; i++) {
|
3554
|
+
acc[i] = XXH64_round(acc[i], XXH_get64bits(input));
|
3555
|
+
input += 8;
|
3556
|
+
}
|
3557
|
+
} else {
|
3558
|
+
acc[0] = XXH64_round(acc[0], XXH_get64bits(input)); input += 8;
|
3559
|
+
acc[1] = XXH64_round(acc[1], XXH_get64bits(input)); input += 8;
|
3560
|
+
acc[2] = XXH64_round(acc[2], XXH_get64bits(input)); input += 8;
|
3561
|
+
acc[3] = XXH64_round(acc[3], XXH_get64bits(input)); input += 8;
|
3562
|
+
}
|
3563
|
+
} while (input < limit);
|
3564
|
+
|
3565
|
+
return input;
|
3566
|
+
}
|
3567
|
+
|
3568
|
+
/*!
|
3569
|
+
* @internal
|
3570
|
+
* @brief Merges the accumulator lanes together for XXH64()
|
3571
|
+
*/
|
3572
|
+
XXH_FORCE_INLINE XXH_PUREF xxh_u64
|
3573
|
+
XXH64_mergeAccs(const xxh_u64 *acc)
|
3574
|
+
{
|
3575
|
+
XXH_ASSERT(acc != NULL);
|
3576
|
+
{
|
3577
|
+
xxh_u64 h64 = XXH_rotl64(acc[0], 1) + XXH_rotl64(acc[1], 7)
|
3578
|
+
+ XXH_rotl64(acc[2], 12) + XXH_rotl64(acc[3], 18);
|
3579
|
+
/* reroll on 32-bit */
|
3580
|
+
if (sizeof(void *) < sizeof(xxh_u64)) {
|
3581
|
+
size_t i;
|
3582
|
+
for (i = 0; i < 4; i++) {
|
3583
|
+
h64 = XXH64_mergeRound(h64, acc[i]);
|
3584
|
+
}
|
3585
|
+
} else {
|
3586
|
+
h64 = XXH64_mergeRound(h64, acc[0]);
|
3587
|
+
h64 = XXH64_mergeRound(h64, acc[1]);
|
3588
|
+
h64 = XXH64_mergeRound(h64, acc[2]);
|
3589
|
+
h64 = XXH64_mergeRound(h64, acc[3]);
|
3590
|
+
}
|
3591
|
+
return h64;
|
3592
|
+
}
|
3593
|
+
}
|
3594
|
+
|
3138
3595
|
/*!
|
3139
3596
|
* @internal
|
3140
3597
|
* @brief Processes the last 0-31 bytes of @p ptr.
|
@@ -3150,7 +3607,7 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash)
|
|
3150
3607
|
* @return The finalized hash
|
3151
3608
|
* @see XXH32_finalize().
|
3152
3609
|
*/
|
3153
|
-
|
3610
|
+
XXH_STATIC XXH_PUREF xxh_u64
|
3154
3611
|
XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
3155
3612
|
{
|
3156
3613
|
if (ptr==NULL) XXH_ASSERT(len == 0);
|
@@ -3200,27 +3657,13 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment
|
|
3200
3657
|
xxh_u64 h64;
|
3201
3658
|
if (input==NULL) XXH_ASSERT(len == 0);
|
3202
3659
|
|
3203
|
-
if (len>=32) {
|
3204
|
-
|
3205
|
-
|
3206
|
-
xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
|
3207
|
-
xxh_u64 v2 = seed + XXH_PRIME64_2;
|
3208
|
-
xxh_u64 v3 = seed + 0;
|
3209
|
-
xxh_u64 v4 = seed - XXH_PRIME64_1;
|
3660
|
+
if (len>=32) { /* Process a large block of data */
|
3661
|
+
xxh_u64 acc[4];
|
3662
|
+
XXH64_initAccs(acc, seed);
|
3210
3663
|
|
3211
|
-
|
3212
|
-
v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8;
|
3213
|
-
v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8;
|
3214
|
-
v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8;
|
3215
|
-
v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8;
|
3216
|
-
} while (input<limit);
|
3217
|
-
|
3218
|
-
h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
|
3219
|
-
h64 = XXH64_mergeRound(h64, v1);
|
3220
|
-
h64 = XXH64_mergeRound(h64, v2);
|
3221
|
-
h64 = XXH64_mergeRound(h64, v3);
|
3222
|
-
h64 = XXH64_mergeRound(h64, v4);
|
3664
|
+
input = XXH64_consumeLong(acc, input, len, align);
|
3223
3665
|
|
3666
|
+
h64 = XXH64_mergeAccs(acc);
|
3224
3667
|
} else {
|
3225
3668
|
h64 = seed + XXH_PRIME64_5;
|
3226
3669
|
}
|
@@ -3276,10 +3719,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH_NOESCAPE XXH64_state_t* statePtr, X
|
|
3276
3719
|
{
|
3277
3720
|
XXH_ASSERT(statePtr != NULL);
|
3278
3721
|
memset(statePtr, 0, sizeof(*statePtr));
|
3279
|
-
statePtr->
|
3280
|
-
statePtr->v[1] = seed + XXH_PRIME64_2;
|
3281
|
-
statePtr->v[2] = seed + 0;
|
3282
|
-
statePtr->v[3] = seed - XXH_PRIME64_1;
|
3722
|
+
XXH64_initAccs(statePtr->acc, seed);
|
3283
3723
|
return XXH_OK;
|
3284
3724
|
}
|
3285
3725
|
|
@@ -3292,42 +3732,36 @@ XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input,
|
|
3292
3732
|
return XXH_OK;
|
3293
3733
|
}
|
3294
3734
|
|
3295
|
-
|
3296
|
-
const xxh_u8* const bEnd = p + len;
|
3735
|
+
state->total_len += len;
|
3297
3736
|
|
3298
|
-
|
3737
|
+
XXH_ASSERT(state->bufferedSize <= sizeof(state->buffer));
|
3738
|
+
if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */
|
3739
|
+
XXH_memcpy(state->buffer + state->bufferedSize, input, len);
|
3740
|
+
state->bufferedSize += (XXH32_hash_t)len;
|
3741
|
+
return XXH_OK;
|
3742
|
+
}
|
3299
3743
|
|
3300
|
-
|
3301
|
-
|
3302
|
-
state->memsize += (xxh_u32)len;
|
3303
|
-
return XXH_OK;
|
3304
|
-
}
|
3744
|
+
{ const xxh_u8* xinput = (const xxh_u8*)input;
|
3745
|
+
const xxh_u8* const bEnd = xinput + len;
|
3305
3746
|
|
3306
|
-
if (state->
|
3307
|
-
XXH_memcpy(
|
3308
|
-
|
3309
|
-
|
3310
|
-
state->
|
3311
|
-
state->
|
3312
|
-
p += 32 - state->memsize;
|
3313
|
-
state->memsize = 0;
|
3747
|
+
if (state->bufferedSize) { /* non-empty buffer => complete first */
|
3748
|
+
XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize);
|
3749
|
+
xinput += sizeof(state->buffer) - state->bufferedSize;
|
3750
|
+
/* and process one round */
|
3751
|
+
(void)XXH64_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned);
|
3752
|
+
state->bufferedSize = 0;
|
3314
3753
|
}
|
3315
3754
|
|
3316
|
-
|
3317
|
-
|
3318
|
-
|
3319
|
-
|
3320
|
-
state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8;
|
3321
|
-
state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8;
|
3322
|
-
state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8;
|
3323
|
-
state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8;
|
3324
|
-
} while (p<=limit);
|
3325
|
-
|
3755
|
+
XXH_ASSERT(xinput <= bEnd);
|
3756
|
+
if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) {
|
3757
|
+
/* Process the remaining data */
|
3758
|
+
xinput = XXH64_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned);
|
3326
3759
|
}
|
3327
3760
|
|
3328
|
-
if (
|
3329
|
-
|
3330
|
-
state->
|
3761
|
+
if (xinput < bEnd) {
|
3762
|
+
/* Copy the leftover to the tmp buffer */
|
3763
|
+
XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput));
|
3764
|
+
state->bufferedSize = (unsigned)(bEnd-xinput);
|
3331
3765
|
}
|
3332
3766
|
}
|
3333
3767
|
|
@@ -3341,18 +3775,14 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t* state
|
|
3341
3775
|
xxh_u64 h64;
|
3342
3776
|
|
3343
3777
|
if (state->total_len >= 32) {
|
3344
|
-
h64 =
|
3345
|
-
h64 = XXH64_mergeRound(h64, state->v[0]);
|
3346
|
-
h64 = XXH64_mergeRound(h64, state->v[1]);
|
3347
|
-
h64 = XXH64_mergeRound(h64, state->v[2]);
|
3348
|
-
h64 = XXH64_mergeRound(h64, state->v[3]);
|
3778
|
+
h64 = XXH64_mergeAccs(state->acc);
|
3349
3779
|
} else {
|
3350
|
-
h64 = state->
|
3780
|
+
h64 = state->acc[2] /*seed*/ + XXH_PRIME64_5;
|
3351
3781
|
}
|
3352
3782
|
|
3353
3783
|
h64 += (xxh_u64) state->total_len;
|
3354
3784
|
|
3355
|
-
return XXH64_finalize(h64,
|
3785
|
+
return XXH64_finalize(h64, state->buffer, (size_t)state->total_len, XXH_aligned);
|
3356
3786
|
}
|
3357
3787
|
#endif /* !XXH_NO_STREAM */
|
3358
3788
|
|
@@ -3387,22 +3817,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can
|
|
3387
3817
|
|
3388
3818
|
/* === Compiler specifics === */
|
3389
3819
|
|
3390
|
-
#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */
|
3391
|
-
# define XXH_RESTRICT /* disable */
|
3392
|
-
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */
|
3393
|
-
# define XXH_RESTRICT restrict
|
3394
|
-
#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \
|
3395
|
-
|| (defined (__clang__)) \
|
3396
|
-
|| (defined (_MSC_VER) && (_MSC_VER >= 1400)) \
|
3397
|
-
|| (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300))
|
3398
|
-
/*
|
3399
|
-
* There are a LOT more compilers that recognize __restrict but this
|
3400
|
-
* covers the major ones.
|
3401
|
-
*/
|
3402
|
-
# define XXH_RESTRICT __restrict
|
3403
|
-
#else
|
3404
|
-
# define XXH_RESTRICT /* disable */
|
3405
|
-
#endif
|
3406
3820
|
|
3407
3821
|
#if (defined(__GNUC__) && (__GNUC__ >= 3)) \
|
3408
3822
|
|| (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \
|
@@ -3416,7 +3830,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can
|
|
3416
3830
|
|
3417
3831
|
#ifndef XXH_HAS_INCLUDE
|
3418
3832
|
# ifdef __has_include
|
3419
|
-
|
3833
|
+
/*
|
3834
|
+
* Not defined as XXH_HAS_INCLUDE(x) (function-like) because
|
3835
|
+
* this causes segfaults in Apple Clang 4.2 (on Mac OS X 10.7 Lion)
|
3836
|
+
*/
|
3837
|
+
# define XXH_HAS_INCLUDE __has_include
|
3420
3838
|
# else
|
3421
3839
|
# define XXH_HAS_INCLUDE(x) 0
|
3422
3840
|
# endif
|
@@ -3437,6 +3855,8 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can
|
|
3437
3855
|
# include <immintrin.h>
|
3438
3856
|
# elif defined(__SSE2__)
|
3439
3857
|
# include <emmintrin.h>
|
3858
|
+
# elif defined(__loongarch_sx)
|
3859
|
+
# include <lsxintrin.h>
|
3440
3860
|
# endif
|
3441
3861
|
#endif
|
3442
3862
|
|
@@ -3533,33 +3953,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can
|
|
3533
3953
|
* implementation.
|
3534
3954
|
*/
|
3535
3955
|
# define XXH_VECTOR XXH_SCALAR
|
3536
|
-
/*!
|
3537
|
-
* @ingroup tuning
|
3538
|
-
* @brief Possible values for @ref XXH_VECTOR.
|
3539
|
-
*
|
3540
|
-
* Note that these are actually implemented as macros.
|
3541
|
-
*
|
3542
|
-
* If this is not defined, it is detected automatically.
|
3543
|
-
* internal macro XXH_X86DISPATCH overrides this.
|
3544
|
-
*/
|
3545
|
-
enum XXH_VECTOR_TYPE /* fake enum */ {
|
3546
|
-
XXH_SCALAR = 0, /*!< Portable scalar version */
|
3547
|
-
XXH_SSE2 = 1, /*!<
|
3548
|
-
* SSE2 for Pentium 4, Opteron, all x86_64.
|
3549
|
-
*
|
3550
|
-
* @note SSE2 is also guaranteed on Windows 10, macOS, and
|
3551
|
-
* Android x86.
|
3552
|
-
*/
|
3553
|
-
XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */
|
3554
|
-
XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */
|
3555
|
-
XXH_NEON = 4, /*!<
|
3556
|
-
* NEON for most ARMv7-A, all AArch64, and WASM SIMD128
|
3557
|
-
* via the SIMDeverywhere polyfill provided with the
|
3558
|
-
* Emscripten SDK.
|
3559
|
-
*/
|
3560
|
-
XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */
|
3561
|
-
XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */
|
3562
|
-
};
|
3563
3956
|
/*!
|
3564
3957
|
* @ingroup tuning
|
3565
3958
|
* @brief Selects the minimum alignment for XXH3's accumulators.
|
@@ -3574,13 +3967,6 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
|
|
3574
3967
|
|
3575
3968
|
/* Actual definition */
|
3576
3969
|
#ifndef XXH_DOXYGEN
|
3577
|
-
# define XXH_SCALAR 0
|
3578
|
-
# define XXH_SSE2 1
|
3579
|
-
# define XXH_AVX2 2
|
3580
|
-
# define XXH_AVX512 3
|
3581
|
-
# define XXH_NEON 4
|
3582
|
-
# define XXH_VSX 5
|
3583
|
-
# define XXH_SVE 6
|
3584
3970
|
#endif
|
3585
3971
|
|
3586
3972
|
#ifndef XXH_VECTOR /* can be defined on command line */
|
@@ -3605,6 +3991,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
|
|
3605
3991
|
|| (defined(__s390x__) && defined(__VEC__)) \
|
3606
3992
|
&& defined(__GNUC__) /* TODO: IBM XL */
|
3607
3993
|
# define XXH_VECTOR XXH_VSX
|
3994
|
+
# elif defined(__loongarch_sx)
|
3995
|
+
# define XXH_VECTOR XXH_LSX
|
3608
3996
|
# else
|
3609
3997
|
# define XXH_VECTOR XXH_SCALAR
|
3610
3998
|
# endif
|
@@ -3642,6 +4030,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
|
|
3642
4030
|
# define XXH_ACC_ALIGN 64
|
3643
4031
|
# elif XXH_VECTOR == XXH_SVE /* sve */
|
3644
4032
|
# define XXH_ACC_ALIGN 64
|
4033
|
+
# elif XXH_VECTOR == XXH_LSX /* lsx */
|
4034
|
+
# define XXH_ACC_ALIGN 64
|
3645
4035
|
# endif
|
3646
4036
|
#endif
|
3647
4037
|
|
@@ -3655,7 +4045,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
|
|
3655
4045
|
#endif
|
3656
4046
|
|
3657
4047
|
#if defined(__GNUC__) || defined(__clang__)
|
3658
|
-
# define XXH_ALIASING __attribute__((
|
4048
|
+
# define XXH_ALIASING __attribute__((__may_alias__))
|
3659
4049
|
#else
|
3660
4050
|
# define XXH_ALIASING /* nothing */
|
3661
4051
|
#endif
|
@@ -4408,8 +4798,6 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
|
|
4408
4798
|
}
|
4409
4799
|
}
|
4410
4800
|
|
4411
|
-
#define XXH3_MIDSIZE_MAX 240
|
4412
|
-
|
4413
4801
|
XXH_NO_INLINE XXH_PUREF XXH64_hash_t
|
4414
4802
|
XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
|
4415
4803
|
const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
|
@@ -5281,6 +5669,71 @@ XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc,
|
|
5281
5669
|
|
5282
5670
|
#endif
|
5283
5671
|
|
5672
|
+
#if (XXH_VECTOR == XXH_LSX)
|
5673
|
+
#define _LSX_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
|
5674
|
+
|
5675
|
+
XXH_FORCE_INLINE void
|
5676
|
+
XXH3_accumulate_512_lsx( void* XXH_RESTRICT acc,
|
5677
|
+
const void* XXH_RESTRICT input,
|
5678
|
+
const void* XXH_RESTRICT secret)
|
5679
|
+
{
|
5680
|
+
XXH_ASSERT((((size_t)acc) & 15) == 0);
|
5681
|
+
{
|
5682
|
+
__m128i* const xacc = (__m128i *) acc;
|
5683
|
+
const __m128i* const xinput = (const __m128i *) input;
|
5684
|
+
const __m128i* const xsecret = (const __m128i *) secret;
|
5685
|
+
|
5686
|
+
for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) {
|
5687
|
+
/* data_vec = xinput[i]; */
|
5688
|
+
__m128i const data_vec = __lsx_vld(xinput + i, 0);
|
5689
|
+
/* key_vec = xsecret[i]; */
|
5690
|
+
__m128i const key_vec = __lsx_vld(xsecret + i, 0);
|
5691
|
+
/* data_key = data_vec ^ key_vec; */
|
5692
|
+
__m128i const data_key = __lsx_vxor_v(data_vec, key_vec);
|
5693
|
+
/* data_key_lo = data_key >> 32; */
|
5694
|
+
__m128i const data_key_lo = __lsx_vsrli_d(data_key, 32);
|
5695
|
+
// __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32);
|
5696
|
+
/* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
|
5697
|
+
__m128i const product = __lsx_vmulwev_d_wu(data_key, data_key_lo);
|
5698
|
+
/* xacc[i] += swap(data_vec); */
|
5699
|
+
__m128i const data_swap = __lsx_vshuf4i_w(data_vec, _LSX_SHUFFLE(1, 0, 3, 2));
|
5700
|
+
__m128i const sum = __lsx_vadd_d(xacc[i], data_swap);
|
5701
|
+
/* xacc[i] += product; */
|
5702
|
+
xacc[i] = __lsx_vadd_d(product, sum);
|
5703
|
+
}
|
5704
|
+
}
|
5705
|
+
}
|
5706
|
+
XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lsx)
|
5707
|
+
|
5708
|
+
XXH_FORCE_INLINE void
|
5709
|
+
XXH3_scrambleAcc_lsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
|
5710
|
+
{
|
5711
|
+
XXH_ASSERT((((size_t)acc) & 15) == 0);
|
5712
|
+
{
|
5713
|
+
__m128i* const xacc = (__m128i*) acc;
|
5714
|
+
const __m128i* const xsecret = (const __m128i *) secret;
|
5715
|
+
const __m128i prime32 = __lsx_vreplgr2vr_w((int)XXH_PRIME32_1);
|
5716
|
+
|
5717
|
+
for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) {
|
5718
|
+
/* xacc[i] ^= (xacc[i] >> 47) */
|
5719
|
+
__m128i const acc_vec = xacc[i];
|
5720
|
+
__m128i const shifted = __lsx_vsrli_d(acc_vec, 47);
|
5721
|
+
__m128i const data_vec = __lsx_vxor_v(acc_vec, shifted);
|
5722
|
+
/* xacc[i] ^= xsecret[i]; */
|
5723
|
+
__m128i const key_vec = __lsx_vld(xsecret + i, 0);
|
5724
|
+
__m128i const data_key = __lsx_vxor_v(data_vec, key_vec);
|
5725
|
+
|
5726
|
+
/* xacc[i] *= XXH_PRIME32_1; */
|
5727
|
+
__m128i const data_key_hi = __lsx_vsrli_d(data_key, 32);
|
5728
|
+
__m128i const prod_lo = __lsx_vmulwev_d_wu(data_key, prime32);
|
5729
|
+
__m128i const prod_hi = __lsx_vmulwev_d_wu(data_key_hi, prime32);
|
5730
|
+
xacc[i] = __lsx_vadd_d(prod_lo, __lsx_vslli_d(prod_hi, 32));
|
5731
|
+
}
|
5732
|
+
}
|
5733
|
+
}
|
5734
|
+
|
5735
|
+
#endif
|
5736
|
+
|
5284
5737
|
/* scalar variants - universal */
|
5285
5738
|
|
5286
5739
|
#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__))
|
@@ -5511,6 +5964,12 @@ typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64);
|
|
5511
5964
|
#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar
|
5512
5965
|
#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
|
5513
5966
|
|
5967
|
+
#elif (XXH_VECTOR == XXH_LSX)
|
5968
|
+
#define XXH3_accumulate_512 XXH3_accumulate_512_lsx
|
5969
|
+
#define XXH3_accumulate XXH3_accumulate_lsx
|
5970
|
+
#define XXH3_scrambleAcc XXH3_scrambleAcc_lsx
|
5971
|
+
#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
|
5972
|
+
|
5514
5973
|
#else /* scalar */
|
5515
5974
|
|
5516
5975
|
#define XXH3_accumulate_512 XXH3_accumulate_512_scalar
|
@@ -5566,7 +6025,7 @@ XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret
|
|
5566
6025
|
acc[1] ^ XXH_readLE64(secret+8) );
|
5567
6026
|
}
|
5568
6027
|
|
5569
|
-
static XXH64_hash_t
|
6028
|
+
static XXH_PUREF XXH64_hash_t
|
5570
6029
|
XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start)
|
5571
6030
|
{
|
5572
6031
|
xxh_u64 result64 = start;
|
@@ -5593,6 +6052,15 @@ XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secre
|
|
5593
6052
|
return XXH3_avalanche(result64);
|
5594
6053
|
}
|
5595
6054
|
|
6055
|
+
/* do not align on 8, so that the secret is different from the accumulator */
|
6056
|
+
#define XXH_SECRET_MERGEACCS_START 11
|
6057
|
+
|
6058
|
+
static XXH_PUREF XXH64_hash_t
|
6059
|
+
XXH3_finalizeLong_64b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 len)
|
6060
|
+
{
|
6061
|
+
return XXH3_mergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, len * XXH_PRIME64_1);
|
6062
|
+
}
|
6063
|
+
|
5596
6064
|
#define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \
|
5597
6065
|
XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 }
|
5598
6066
|
|
@@ -5608,10 +6076,8 @@ XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len,
|
|
5608
6076
|
|
5609
6077
|
/* converge into final hash */
|
5610
6078
|
XXH_STATIC_ASSERT(sizeof(acc) == 64);
|
5611
|
-
/* do not align on 8, so that the secret is different from the accumulator */
|
5612
|
-
#define XXH_SECRET_MERGEACCS_START 11
|
5613
6079
|
XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
|
5614
|
-
return
|
6080
|
+
return XXH3_finalizeLong_64b(acc, (const xxh_u8*)secret, (xxh_u64)len);
|
5615
6081
|
}
|
5616
6082
|
|
5617
6083
|
/*
|
@@ -5747,7 +6213,7 @@ XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH
|
|
5747
6213
|
/* === XXH3 streaming === */
|
5748
6214
|
#ifndef XXH_NO_STREAM
|
5749
6215
|
/*
|
5750
|
-
* Malloc's a pointer that is always aligned to align.
|
6216
|
+
* Malloc's a pointer that is always aligned to @align.
|
5751
6217
|
*
|
5752
6218
|
* This must be freed with `XXH_alignedFree()`.
|
5753
6219
|
*
|
@@ -5815,8 +6281,12 @@ static void XXH_alignedFree(void* p)
|
|
5815
6281
|
/*!
|
5816
6282
|
* @brief Allocate an @ref XXH3_state_t.
|
5817
6283
|
*
|
5818
|
-
*
|
5819
|
-
* @return
|
6284
|
+
* @return An allocated pointer of @ref XXH3_state_t on success.
|
6285
|
+
* @return `NULL` on failure.
|
6286
|
+
*
|
6287
|
+
* @note Must be freed with XXH3_freeState().
|
6288
|
+
*
|
6289
|
+
* @see @ref streaming_example "Streaming Example"
|
5820
6290
|
*/
|
5821
6291
|
XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
|
5822
6292
|
{
|
@@ -5830,9 +6300,13 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
|
|
5830
6300
|
/*!
|
5831
6301
|
* @brief Frees an @ref XXH3_state_t.
|
5832
6302
|
*
|
5833
|
-
* Must be allocated with XXH3_createState().
|
5834
6303
|
* @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState().
|
5835
|
-
*
|
6304
|
+
*
|
6305
|
+
* @return @ref XXH_OK.
|
6306
|
+
*
|
6307
|
+
* @note Must be allocated with XXH3_createState().
|
6308
|
+
*
|
6309
|
+
* @see @ref streaming_example "Streaming Example"
|
5836
6310
|
*/
|
5837
6311
|
XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr)
|
5838
6312
|
{
|
@@ -6111,9 +6585,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t*
|
|
6111
6585
|
if (state->totalLen > XXH3_MIDSIZE_MAX) {
|
6112
6586
|
XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
|
6113
6587
|
XXH3_digest_long(acc, state, secret);
|
6114
|
-
return
|
6115
|
-
secret + XXH_SECRET_MERGEACCS_START,
|
6116
|
-
(xxh_u64)state->totalLen * XXH_PRIME64_1);
|
6588
|
+
return XXH3_finalizeLong_64b(acc, secret, (xxh_u64)state->totalLen);
|
6117
6589
|
}
|
6118
6590
|
/* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */
|
6119
6591
|
if (state->useSeed)
|
@@ -6405,6 +6877,17 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
|
|
6405
6877
|
}
|
6406
6878
|
}
|
6407
6879
|
|
6880
|
+
static XXH_PUREF XXH128_hash_t
|
6881
|
+
XXH3_finalizeLong_128b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, xxh_u64 len)
|
6882
|
+
{
|
6883
|
+
XXH128_hash_t h128;
|
6884
|
+
h128.low64 = XXH3_finalizeLong_64b(acc, secret, len);
|
6885
|
+
h128.high64 = XXH3_mergeAccs(acc, secret + secretSize
|
6886
|
+
- XXH_STRIPE_LEN - XXH_SECRET_MERGEACCS_START,
|
6887
|
+
~(len * XXH_PRIME64_2));
|
6888
|
+
return h128;
|
6889
|
+
}
|
6890
|
+
|
6408
6891
|
XXH_FORCE_INLINE XXH128_hash_t
|
6409
6892
|
XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len,
|
6410
6893
|
const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
|
@@ -6418,16 +6901,7 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len,
|
|
6418
6901
|
/* converge into final hash */
|
6419
6902
|
XXH_STATIC_ASSERT(sizeof(acc) == 64);
|
6420
6903
|
XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
|
6421
|
-
|
6422
|
-
h128.low64 = XXH3_mergeAccs(acc,
|
6423
|
-
secret + XXH_SECRET_MERGEACCS_START,
|
6424
|
-
(xxh_u64)len * XXH_PRIME64_1);
|
6425
|
-
h128.high64 = XXH3_mergeAccs(acc,
|
6426
|
-
secret + secretSize
|
6427
|
-
- sizeof(acc) - XXH_SECRET_MERGEACCS_START,
|
6428
|
-
~((xxh_u64)len * XXH_PRIME64_2));
|
6429
|
-
return h128;
|
6430
|
-
}
|
6904
|
+
return XXH3_finalizeLong_128b(acc, secret, secretSize, (xxh_u64)len);
|
6431
6905
|
}
|
6432
6906
|
|
6433
6907
|
/*
|
@@ -6610,19 +7084,10 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_
|
|
6610
7084
|
XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
|
6611
7085
|
XXH3_digest_long(acc, state, secret);
|
6612
7086
|
XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
|
6613
|
-
|
6614
|
-
h128.low64 = XXH3_mergeAccs(acc,
|
6615
|
-
secret + XXH_SECRET_MERGEACCS_START,
|
6616
|
-
(xxh_u64)state->totalLen * XXH_PRIME64_1);
|
6617
|
-
h128.high64 = XXH3_mergeAccs(acc,
|
6618
|
-
secret + state->secretLimit + XXH_STRIPE_LEN
|
6619
|
-
- sizeof(acc) - XXH_SECRET_MERGEACCS_START,
|
6620
|
-
~((xxh_u64)state->totalLen * XXH_PRIME64_2));
|
6621
|
-
return h128;
|
6622
|
-
}
|
7087
|
+
return XXH3_finalizeLong_128b(acc, secret, state->secretLimit + XXH_STRIPE_LEN, (xxh_u64)state->totalLen);
|
6623
7088
|
}
|
6624
7089
|
/* len <= XXH3_MIDSIZE_MAX : short code */
|
6625
|
-
if (state->
|
7090
|
+
if (state->useSeed)
|
6626
7091
|
return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
|
6627
7092
|
return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen),
|
6628
7093
|
secret, state->secretLimit + XXH_STRIPE_LEN);
|