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.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * xxHash - Extremely Fast Hash algorithm
3
3
  * Header File
4
- * Copyright (C) 2012-2021 Yann Collet
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__((unused))
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(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
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(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
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__((const))
465
- # define XXH_PUREF __attribute__((pure))
466
- # define XXH_MALLOCF __attribute__((malloc))
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 2
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
- # include <stdint.h>
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 hash value.
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
- * Must be freed with XXH32_freeState().
615
- * @return An allocated XXH32_state_t on success, `NULL` on failure.
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
- * @return XXH_OK.
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, @ref XXH_ERROR on failure.
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, @ref XXH_ERROR on failure.
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 The @ref XXH32_canonical_t pointer to be stored to.
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__((noescape))
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
- # include <stdint.h>
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 hash.
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
- * Must be freed with XXH64_freeState().
889
- * @return An allocated XXH64_state_t on success, `NULL` on failure.
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
- * @return XXH_OK.
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, @ref XXH_ERROR on failure.
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, @ref XXH_ERROR on failure.
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
- * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of 0, however
1057
- * it may have slightly better performance due to constant propagation of the
1058
- * defaults.
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
- * This variant generates a custom secret on the fly based on default secret
1073
- * altered using the `seed` value.
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
- * While this operation is decently fast, note that it's not completely free.
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
- * @param input The data to hash
1081
- * @param length The length
1082
- * @param seed The 64-bit seed to alter the state.
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 "XXH3_generateSecret()" instead (see below).
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, @ref XXH_ERROR on failure.
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 state.
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, @ref XXH_ERROR on failure.
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
- * XXH3_64bits_reset_withSecret():
1179
- * `secret` is referenced, it _must outlive_ the hash streaming session.
1180
- * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`,
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, @ref XXH_ERROR on failure.
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 Unseeded 128-bit variant of XXH3
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, however
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
- * XXH32(), XXH64(), XXH3_64bits(): equivalent for the other xxHash algorithms
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 Seeded 128-bit variant of XXH3. @see XXH3_64bits_withSeed(). */
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
- /*! @brief Custom secret 128-bit variant of XXH3. @see XXH3_64bits_withSecret(). */
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, @ref XXH_ERROR on failure.
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
- * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_128bits_update().
1301
- * Digest will be equivalent to `XXH3_128bits_withSeed()`.
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 The state struct to reset.
1304
- * @param seed The 64-bit seed to alter the state.
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, @ref XXH_ERROR on failure.
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
- * @pre
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
- * XXH128_isEqual():
1359
- * Return: 1 if `h1` and `h2` are equal, 0 if they are not.
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
- * @return: >0 if *h128_1 > *h128_2
1368
- * =0 if *h128_1 == *h128_2
1369
- * <0 if *h128_1 < *h128_2
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 The @ref XXH128_canonical_t pointer to be stored to.
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 v[4]; /*!< Accumulator lanes */
1444
- XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */
1445
- XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */
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 v[4]; /*!< Accumulator lanes */
1467
- XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */
1468
- XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */
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
- # include <stdalign.h>
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
- * simple alias to pre-selected XXH3_128bits variant
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
- * XXH3_generateSecret():
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[XXH3_SECRET_SIZE_MIN];
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
- * These variants generate hash values using either
1692
- * @p seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes)
1693
- * or @p secret for "large" keys (>= XXH3_MIDSIZE_MAX).
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
- /*! @copydoc XXH3_64bits_withSecretandSeed() */
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
- /*! @copydoc XXH3_64bits_withSecretandSeed() */
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
- /*! @copydoc XXH3_64bits_withSecretandSeed() */
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__((unused))
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__((always_inline, unused))
2111
- # define XXH_NO_INLINE static __attribute__((noinline))
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
- # include <stdint.h>
2210
- typedef uint8_t xxh_u8;
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
- typedef unsigned char xxh_u8;
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__((packed)) unalign;
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__((aligned(1))) xxh_u32 xxh_unalign32;
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 the only thing that prevents GCC and Clang from
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
- const xxh_u8* const bEnd = input + len;
2767
- const xxh_u8* const limit = bEnd - 15;
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
- do {
2774
- v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4;
2775
- v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4;
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->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
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
- { const xxh_u8* p = (const xxh_u8*)input;
2855
- const xxh_u8* const bEnd = p + len;
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
- state->total_len_32 += (XXH32_hash_t)len;
2858
- state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16));
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
- if (state->memsize + len < 16) { /* fill in tmp buffer */
2861
- XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len);
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->memsize) { /* some data left from previous update */
2867
- XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize);
2868
- { const xxh_u32* p32 = state->mem32;
2869
- state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++;
2870
- state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++;
2871
- state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++;
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
- if (p <= bEnd-16) {
2879
- const xxh_u8* const limit = bEnd - 16;
2880
-
2881
- do {
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 (p < bEnd) {
2891
- XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
2892
- state->memsize = (unsigned)(bEnd-p);
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 = XXH_rotl32(state->v[0], 1)
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->v[2] /* == seed */ + XXH_PRIME32_5;
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, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned);
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__((packed)) unalign64;
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__((aligned(1))) xxh_u64 xxh_unalign64;
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
- static XXH_PUREF xxh_u64
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
- const xxh_u8* const bEnd = input + len;
3205
- const xxh_u8* const limit = bEnd - 31;
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
- do {
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->v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
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
- { const xxh_u8* p = (const xxh_u8*)input;
3296
- const xxh_u8* const bEnd = p + len;
3735
+ state->total_len += len;
3297
3736
 
3298
- state->total_len += len;
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
- if (state->memsize + len < 32) { /* fill in tmp buffer */
3301
- XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len);
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->memsize) { /* tmp buffer is full */
3307
- XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize);
3308
- state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0));
3309
- state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1));
3310
- state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2));
3311
- state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3));
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
- if (p+32 <= bEnd) {
3317
- const xxh_u8* const limit = bEnd - 32;
3318
-
3319
- do {
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 (p < bEnd) {
3329
- XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
3330
- state->memsize = (unsigned)(bEnd-p);
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 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18);
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->v[2] /*seed*/ + XXH_PRIME64_5;
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, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned);
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
- # define XXH_HAS_INCLUDE(x) __has_include(x)
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__((may_alias))
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 XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1);
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
- * Must be freed with XXH3_freeState().
5819
- * @return An allocated XXH3_state_t on success, `NULL` on failure.
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
- * @return XXH_OK.
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 XXH3_mergeAccs(acc,
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
- { XXH128_hash_t h128;
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
- { XXH128_hash_t h128;
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->seed)
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);