digest-xxhash 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d340515d2a46b42bc5c332465a18de3bac90949c8e4d694a040b537d47bf742
4
- data.tar.gz: 347fd239d94cb06cef8760e6f9146b4c7aaa70032ae74005cb2f81ba703e3217
3
+ metadata.gz: dd4724a81a8591422e26de9b1374b843cd6658c9b489d30e8aa1cb1079d85da6
4
+ data.tar.gz: 430d6b738c1e4ccbfa9d876de7c797b364c3a8ed8c7a027a361aca87c149c2a2
5
5
  SHA512:
6
- metadata.gz: e15847af311052541303513833fb79881e4798a3fac0127b26a41bce200e6f8c141dae525c93746710da1d0b5977e7fbce03302f74c8d88181a0d24215c3fa71
7
- data.tar.gz: 361d7b1e29837803ade9545a4c9f86f01275d4b21680a69a3f154d1849b6d31bd5d80f4ff3c291e1d74bab0b1be28e66ee1f9380f040b7570e85124744d6548b
6
+ metadata.gz: 1a632aa6781227200270fdcf82afe3df388ef409e157e19e7a86d71b3c627d193e46a8f86a343deb864ae1463f2300735fd42d8e53b3c9f0af78cddb8f528ee7
7
+ data.tar.gz: eb4cf2422fc4e74034599ebf7012aef294230469de57cfab9105061480113ed4b74b799815de8bd2b1d1d3eafc5fdb2cbe0478c220565e6bda0479015dd7b7c7
@@ -43,7 +43,7 @@ Gem::Specification.new do |spec|
43
43
  spec.require_paths = ["lib"]
44
44
 
45
45
  spec.add_development_dependency "rake"
46
- spec.add_development_dependency "rake-compiler", "~> 1.0", "!= 1.1.3", "!= 1.1.4", "!= 1.1.5"
46
+ spec.add_development_dependency "rake-compiler", "~> 1.2", ">= 1.2.3"
47
47
  spec.add_development_dependency "minitest", "~> 5.8"
48
48
 
49
49
  spec.extensions = %w[ext/digest/xxhash/extconf.rb]
@@ -182,6 +182,33 @@ extern "C" {
182
182
  * @{
183
183
  */
184
184
  #ifdef XXH_DOXYGEN
185
+ /*!
186
+ * @brief Gives access to internal state declaration, required for static allocation.
187
+ *
188
+ * Incompatible with dynamic linking, due to risks of ABI changes.
189
+ *
190
+ * Usage:
191
+ * @code{.c}
192
+ * #define XXH_STATIC_LINKING_ONLY
193
+ * #include "xxhash.h"
194
+ * @endcode
195
+ */
196
+ # define XXH_STATIC_LINKING_ONLY
197
+ /* Do not undef XXH_STATIC_LINKING_ONLY for Doxygen */
198
+
199
+ /*!
200
+ * @brief Gives access to internal definitions.
201
+ *
202
+ * Usage:
203
+ * @code{.c}
204
+ * #define XXH_STATIC_LINKING_ONLY
205
+ * #define XXH_IMPLEMENTATION
206
+ * #include "xxhash.h"
207
+ * @endcode
208
+ */
209
+ # define XXH_IMPLEMENTATION
210
+ /* Do not undef XXH_IMPLEMENTATION for Doxygen */
211
+
185
212
  /*!
186
213
  * @brief Exposes the implementation and marks all functions as `inline`.
187
214
  *
@@ -448,7 +475,7 @@ extern "C" {
448
475
  ***************************************/
449
476
  #define XXH_VERSION_MAJOR 0
450
477
  #define XXH_VERSION_MINOR 8
451
- #define XXH_VERSION_RELEASE 1
478
+ #define XXH_VERSION_RELEASE 2
452
479
  /*! @brief Version number, encoded as two digits each */
453
480
  #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
454
481
 
@@ -710,32 +737,41 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t
710
737
  XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
711
738
 
712
739
 
740
+ /*! @cond Doxygen ignores this part */
713
741
  #ifdef __has_attribute
714
742
  # define XXH_HAS_ATTRIBUTE(x) __has_attribute(x)
715
743
  #else
716
744
  # define XXH_HAS_ATTRIBUTE(x) 0
717
745
  #endif
746
+ /*! @endcond */
718
747
 
748
+ /*! @cond Doxygen ignores this part */
719
749
  /*
720
750
  * C23 __STDC_VERSION__ number hasn't been specified yet. For now
721
751
  * leave as `201711L` (C17 + 1).
722
752
  * TODO: Update to correct value when its been specified.
723
753
  */
724
754
  #define XXH_C23_VN 201711L
755
+ /*! @endcond */
725
756
 
757
+ /*! @cond Doxygen ignores this part */
726
758
  /* C-language Attributes are added in C23. */
727
759
  #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= XXH_C23_VN) && defined(__has_c_attribute)
728
760
  # define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
729
761
  #else
730
762
  # define XXH_HAS_C_ATTRIBUTE(x) 0
731
763
  #endif
764
+ /*! @endcond */
732
765
 
766
+ /*! @cond Doxygen ignores this part */
733
767
  #if defined(__cplusplus) && defined(__has_cpp_attribute)
734
768
  # define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
735
769
  #else
736
770
  # define XXH_HAS_CPP_ATTRIBUTE(x) 0
737
771
  #endif
772
+ /*! @endcond */
738
773
 
774
+ /*! @cond Doxygen ignores this part */
739
775
  /*
740
776
  * Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute
741
777
  * introduced in CPP17 and C23.
@@ -749,7 +785,9 @@ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canoni
749
785
  #else
750
786
  # define XXH_FALLTHROUGH /* fallthrough */
751
787
  #endif
788
+ /*! @endcond */
752
789
 
790
+ /*! @cond Doxygen ignores this part */
753
791
  /*
754
792
  * Define XXH_NOESCAPE for annotated pointers in public API.
755
793
  * https://clang.llvm.org/docs/AttributeReference.html#noescape
@@ -760,6 +798,7 @@ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canoni
760
798
  #else
761
799
  # define XXH_NOESCAPE
762
800
  #endif
801
+ /*! @endcond */
763
802
 
764
803
 
765
804
  /*!
@@ -842,17 +881,113 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size
842
881
  * @see XXH64_state_s for details.
843
882
  */
844
883
  typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
884
+
885
+ /*!
886
+ * @brief Allocates an @ref XXH64_state_t.
887
+ *
888
+ * Must be freed with XXH64_freeState().
889
+ * @return An allocated XXH64_state_t on success, `NULL` on failure.
890
+ */
845
891
  XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void);
892
+
893
+ /*!
894
+ * @brief Frees an @ref XXH64_state_t.
895
+ *
896
+ * Must be allocated with XXH64_createState().
897
+ * @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState().
898
+ * @return XXH_OK.
899
+ */
846
900
  XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
901
+
902
+ /*!
903
+ * @brief Copies one @ref XXH64_state_t to another.
904
+ *
905
+ * @param dst_state The state to copy to.
906
+ * @param src_state The state to copy from.
907
+ * @pre
908
+ * @p dst_state and @p src_state must not be `NULL` and must not overlap.
909
+ */
847
910
  XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const XXH64_state_t* src_state);
848
911
 
912
+ /*!
913
+ * @brief Resets an @ref XXH64_state_t to begin a new hash.
914
+ *
915
+ * This function resets and seeds a state. Call it before @ref XXH64_update().
916
+ *
917
+ * @param statePtr The state struct to reset.
918
+ * @param seed The 64-bit seed to alter the hash result predictably.
919
+ *
920
+ * @pre
921
+ * @p statePtr must not be `NULL`.
922
+ *
923
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
924
+ */
849
925
  XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed);
926
+
927
+ /*!
928
+ * @brief Consumes a block of @p input to an @ref XXH64_state_t.
929
+ *
930
+ * Call this to incrementally consume blocks of data.
931
+ *
932
+ * @param statePtr The state struct to update.
933
+ * @param input The block of data to be hashed, at least @p length bytes in size.
934
+ * @param length The length of @p input, in bytes.
935
+ *
936
+ * @pre
937
+ * @p statePtr must not be `NULL`.
938
+ * @pre
939
+ * The memory between @p input and @p input + @p length must be valid,
940
+ * readable, contiguous memory. However, if @p length is `0`, @p input may be
941
+ * `NULL`. In C++, this also must be *TriviallyCopyable*.
942
+ *
943
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
944
+ */
850
945
  XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length);
946
+
947
+ /*!
948
+ * @brief Returns the calculated hash value from an @ref XXH64_state_t.
949
+ *
950
+ * @note
951
+ * Calling XXH64_digest() will not affect @p statePtr, so you can update,
952
+ * digest, and update again.
953
+ *
954
+ * @param statePtr The state struct to calculate the hash from.
955
+ *
956
+ * @pre
957
+ * @p statePtr must not be `NULL`.
958
+ *
959
+ * @return The calculated xxHash64 value from that state.
960
+ */
851
961
  XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr);
852
962
  #endif /* !XXH_NO_STREAM */
853
963
  /******* Canonical representation *******/
964
+
965
+ /*!
966
+ * @brief Canonical (big endian) representation of @ref XXH64_hash_t.
967
+ */
854
968
  typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t;
969
+
970
+ /*!
971
+ * @brief Converts an @ref XXH64_hash_t to a big endian @ref XXH64_canonical_t.
972
+ *
973
+ * @param dst The @ref XXH64_canonical_t pointer to be stored to.
974
+ * @param hash The @ref XXH64_hash_t to be converted.
975
+ *
976
+ * @pre
977
+ * @p dst must not be `NULL`.
978
+ */
855
979
  XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash);
980
+
981
+ /*!
982
+ * @brief Converts an @ref XXH64_canonical_t to a native @ref XXH64_hash_t.
983
+ *
984
+ * @param src The @ref XXH64_canonical_t to convert.
985
+ *
986
+ * @pre
987
+ * @p src must not be `NULL`.
988
+ *
989
+ * @return The converted hash.
990
+ */
856
991
  XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src);
857
992
 
858
993
  #ifndef XXH_NO_XXH3
@@ -884,10 +1019,18 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const
884
1019
  * at competitive speeds, even without vector support. Further details are
885
1020
  * explained in the implementation.
886
1021
  *
887
- * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8,
888
- * ZVector and scalar targets. This can be controlled via the @ref XXH_VECTOR
889
- * macro. For the x86 family, an automatic dispatcher is included separately
890
- * in @ref xxh_x86dispatch.c.
1022
+ * XXH3 has a fast scalar implementation, but it also includes accelerated SIMD
1023
+ * implementations for many common platforms:
1024
+ * - AVX512
1025
+ * - AVX2
1026
+ * - SSE2
1027
+ * - ARM NEON
1028
+ * - WebAssembly SIMD128
1029
+ * - POWER8 VSX
1030
+ * - s390x ZVector
1031
+ * This can be controlled via the @ref XXH_VECTOR macro, but it automatically
1032
+ * selects the best version according to predefined macros. For the x86 family, an
1033
+ * automatic runtime dispatcher is included separately in @ref xxh_x86dispatch.c.
891
1034
  *
892
1035
  * XXH3 implementation is portable:
893
1036
  * it has a generic C90 formulation that can be compiled on any platform,
@@ -987,20 +1130,50 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const
987
1130
  typedef struct XXH3_state_s XXH3_state_t;
988
1131
  XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void);
989
1132
  XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr);
1133
+
1134
+ /*!
1135
+ * @brief Copies one @ref XXH3_state_t to another.
1136
+ *
1137
+ * @param dst_state The state to copy to.
1138
+ * @param src_state The state to copy from.
1139
+ * @pre
1140
+ * @p dst_state and @p src_state must not be `NULL` and must not overlap.
1141
+ */
990
1142
  XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOESCAPE const XXH3_state_t* src_state);
991
1143
 
992
- /*
993
- * XXH3_64bits_reset():
994
- * Initialize with default parameters.
995
- * digest will be equivalent to `XXH3_64bits()`.
1144
+ /*!
1145
+ * @brief Resets an @ref XXH3_state_t to begin a new hash.
1146
+ *
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
+ * @param statePtr The state struct to reset.
1151
+ *
1152
+ * @pre
1153
+ * @p statePtr must not be `NULL`.
1154
+ *
1155
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
1156
+ *
996
1157
  */
997
1158
  XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr);
998
- /*
999
- * XXH3_64bits_reset_withSeed():
1000
- * Generate a custom secret from `seed`, and store it into `statePtr`.
1001
- * digest will be equivalent to `XXH3_64bits_withSeed()`.
1159
+
1160
+ /*!
1161
+ * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash.
1162
+ *
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
+ * @param statePtr The state struct to reset.
1167
+ * @param seed The 64-bit seed to alter the state.
1168
+ *
1169
+ * @pre
1170
+ * @p statePtr must not be `NULL`.
1171
+ *
1172
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
1173
+ *
1002
1174
  */
1003
1175
  XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed);
1176
+
1004
1177
  /*!
1005
1178
  * XXH3_64bits_reset_withSecret():
1006
1179
  * `secret` is referenced, it _must outlive_ the hash streaming session.
@@ -1012,7 +1185,40 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_
1012
1185
  */
1013
1186
  XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize);
1014
1187
 
1188
+ /*!
1189
+ * @brief Consumes a block of @p input to an @ref XXH3_state_t.
1190
+ *
1191
+ * Call this to incrementally consume blocks of data.
1192
+ *
1193
+ * @param statePtr The state struct to update.
1194
+ * @param input The block of data to be hashed, at least @p length bytes in size.
1195
+ * @param length The length of @p input, in bytes.
1196
+ *
1197
+ * @pre
1198
+ * @p statePtr must not be `NULL`.
1199
+ * @pre
1200
+ * The memory between @p input and @p input + @p length must be valid,
1201
+ * readable, contiguous memory. However, if @p length is `0`, @p input may be
1202
+ * `NULL`. In C++, this also must be *TriviallyCopyable*.
1203
+ *
1204
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
1205
+ */
1015
1206
  XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length);
1207
+
1208
+ /*!
1209
+ * @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t.
1210
+ *
1211
+ * @note
1212
+ * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update,
1213
+ * digest, and update again.
1214
+ *
1215
+ * @param statePtr The state struct to calculate the hash from.
1216
+ *
1217
+ * @pre
1218
+ * @p statePtr must not be `NULL`.
1219
+ *
1220
+ * @return The calculated XXH3 64-bit hash value from that state.
1221
+ */
1016
1222
  XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr);
1017
1223
  #endif /* !XXH_NO_STREAM */
1018
1224
 
@@ -1072,11 +1278,75 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE cons
1072
1278
  * All reset and streaming functions have same meaning as their 64-bit counterpart.
1073
1279
  */
1074
1280
 
1281
+ /*!
1282
+ * @brief Resets an @ref XXH3_state_t to begin a new hash.
1283
+ *
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
+ * @param statePtr The state struct to reset.
1288
+ *
1289
+ * @pre
1290
+ * @p statePtr must not be `NULL`.
1291
+ *
1292
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
1293
+ *
1294
+ */
1075
1295
  XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr);
1296
+
1297
+ /*!
1298
+ * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash.
1299
+ *
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()`.
1302
+ *
1303
+ * @param statePtr The state struct to reset.
1304
+ * @param seed The 64-bit seed to alter the state.
1305
+ *
1306
+ * @pre
1307
+ * @p statePtr must not be `NULL`.
1308
+ *
1309
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
1310
+ *
1311
+ */
1076
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(). */
1077
1314
  XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize);
1078
1315
 
1316
+ /*!
1317
+ * @brief Consumes a block of @p input to an @ref XXH3_state_t.
1318
+ *
1319
+ * Call this to incrementally consume blocks of data.
1320
+ *
1321
+ * @param statePtr The state struct to update.
1322
+ * @param input The block of data to be hashed, at least @p length bytes in size.
1323
+ * @param length The length of @p input, in bytes.
1324
+ *
1325
+ * @pre
1326
+ * @p statePtr must not be `NULL`.
1327
+ * @pre
1328
+ * The memory between @p input and @p input + @p length must be valid,
1329
+ * readable, contiguous memory. However, if @p length is `0`, @p input may be
1330
+ * `NULL`. In C++, this also must be *TriviallyCopyable*.
1331
+ *
1332
+ * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
1333
+ */
1079
1334
  XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length);
1335
+
1336
+ /*!
1337
+ * @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t.
1338
+ *
1339
+ * @note
1340
+ * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update,
1341
+ * digest, and update again.
1342
+ *
1343
+ * @param statePtr The state struct to calculate the hash from.
1344
+ *
1345
+ * @pre
1346
+ * @p statePtr must not be `NULL`.
1347
+ *
1348
+ * @return The calculated XXH3 128-bit hash value from that state.
1349
+ */
1080
1350
  XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr);
1081
1351
  #endif /* !XXH_NO_STREAM */
1082
1352
 
@@ -1103,7 +1373,29 @@ XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOE
1103
1373
 
1104
1374
  /******* Canonical representation *******/
1105
1375
  typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t;
1376
+
1377
+
1378
+ /*!
1379
+ * @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t.
1380
+ *
1381
+ * @param dst The @ref XXH128_canonical_t pointer to be stored to.
1382
+ * @param hash The @ref XXH128_hash_t to be converted.
1383
+ *
1384
+ * @pre
1385
+ * @p dst must not be `NULL`.
1386
+ */
1106
1387
  XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash);
1388
+
1389
+ /*!
1390
+ * @brief Converts an @ref XXH128_canonical_t to a native @ref XXH128_hash_t.
1391
+ *
1392
+ * @param src The @ref XXH128_canonical_t to convert.
1393
+ *
1394
+ * @pre
1395
+ * @p src must not be `NULL`.
1396
+ *
1397
+ * @return The converted hash.
1398
+ */
1107
1399
  XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src);
1108
1400
 
1109
1401
 
@@ -1213,6 +1505,7 @@ struct XXH64_state_s {
1213
1505
  #define XXH3_INTERNALBUFFER_SIZE 256
1214
1506
 
1215
1507
  /*!
1508
+ * @internal
1216
1509
  * @brief Default size of the secret buffer (and @ref XXH3_kSecret).
1217
1510
  *
1218
1511
  * This is the size used in @ref XXH3_kSecret and the seeded functions.
@@ -1539,7 +1832,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr,
1539
1832
  * inline small `memcpy()` calls, and it might also be faster on big-endian
1540
1833
  * systems which lack a native byteswap instruction. However, some compilers
1541
1834
  * will emit literal byteshifts even if the target supports unaligned access.
1542
- * .
1835
+ *
1543
1836
  *
1544
1837
  * @warning
1545
1838
  * Methods 1 and 2 rely on implementation-defined behavior. Use these with
@@ -1858,7 +2151,11 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
1858
2151
  # include <assert.h> /* note: can still be disabled with NDEBUG */
1859
2152
  # define XXH_ASSERT(c) assert(c)
1860
2153
  #else
1861
- # define XXH_ASSERT(c) XXH_ASSUME(c)
2154
+ # if defined(__INTEL_COMPILER)
2155
+ # define XXH_ASSERT(c) XXH_ASSUME((unsigned char) (c))
2156
+ # else
2157
+ # define XXH_ASSERT(c) XXH_ASSUME(c)
2158
+ # endif
1862
2159
  #endif
1863
2160
 
1864
2161
  /* note: use after variable declarations */
@@ -1895,10 +2192,12 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
1895
2192
  # define XXH_COMPILER_GUARD(var) ((void)0)
1896
2193
  #endif
1897
2194
 
1898
- #if defined(__clang__)
1899
- # define XXH_COMPILER_GUARD_W(var) __asm__("" : "+w" (var))
2195
+ /* Specifically for NEON vectors which use the "w" constraint, on
2196
+ * Clang. */
2197
+ #if defined(__clang__) && defined(__ARM_ARCH) && !defined(__wasm__)
2198
+ # define XXH_COMPILER_GUARD_CLANG_NEON(var) __asm__("" : "+w" (var))
1900
2199
  #else
1901
- # define XXH_COMPILER_GUARD_W(var) ((void)0)
2200
+ # define XXH_COMPILER_GUARD_CLANG_NEON(var) ((void)0)
1902
2201
  #endif
1903
2202
 
1904
2203
  /* *************************************
@@ -1915,6 +2214,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
1915
2214
  typedef XXH32_hash_t xxh_u32;
1916
2215
 
1917
2216
  #ifdef XXH_OLD_NAMES
2217
+ # warning "XXH_OLD_NAMES is planned to be removed starting v0.9. If the program depends on it, consider moving away from it by employing newer type names directly"
1918
2218
  # define BYTE xxh_u8
1919
2219
  # define U8 xxh_u8
1920
2220
  # define U32 xxh_u32
@@ -2287,7 +2587,7 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
2287
2587
  acc += input * XXH_PRIME32_2;
2288
2588
  acc = XXH_rotl32(acc, 13);
2289
2589
  acc *= XXH_PRIME32_1;
2290
- #if (defined(__SSE4_1__) || defined(__aarch64__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
2590
+ #if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
2291
2591
  /*
2292
2592
  * UGLY HACK:
2293
2593
  * A compiler fence is the only thing that prevents GCC and Clang from
@@ -2320,6 +2620,9 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
2320
2620
  * This is also enabled on AArch64, as Clang is *very aggressive* in vectorizing
2321
2621
  * the loop. NEON is only faster on the A53, and with the newer cores, it is less
2322
2622
  * than half the speed.
2623
+ *
2624
+ * Additionally, this is used on WASM SIMD128 because it JITs to the same
2625
+ * SIMD instructions and has the same issue.
2323
2626
  */
2324
2627
  XXH_COMPILER_GUARD(acc);
2325
2628
  #endif
@@ -3111,13 +3414,22 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can
3111
3414
  # define XXH_unlikely(x) (x)
3112
3415
  #endif
3113
3416
 
3417
+ #ifndef XXH_HAS_INCLUDE
3418
+ # ifdef __has_include
3419
+ # define XXH_HAS_INCLUDE(x) __has_include(x)
3420
+ # else
3421
+ # define XXH_HAS_INCLUDE(x) 0
3422
+ # endif
3423
+ #endif
3424
+
3114
3425
  #if defined(__GNUC__) || defined(__clang__)
3115
3426
  # if defined(__ARM_FEATURE_SVE)
3116
3427
  # include <arm_sve.h>
3117
3428
  # endif
3118
3429
  # if defined(__ARM_NEON__) || defined(__ARM_NEON) \
3119
3430
  || (defined(_M_ARM) && _M_ARM >= 7) \
3120
- || defined(_M_ARM64) || defined(_M_ARM64EC)
3431
+ || defined(_M_ARM64) || defined(_M_ARM64EC) \
3432
+ || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE(<arm_neon.h>)) /* WASM SIMD128 via SIMDe */
3121
3433
  # define inline __inline__ /* circumvent a clang bug */
3122
3434
  # include <arm_neon.h>
3123
3435
  # undef inline
@@ -3228,7 +3540,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can
3228
3540
  * Note that these are actually implemented as macros.
3229
3541
  *
3230
3542
  * If this is not defined, it is detected automatically.
3231
- * @ref XXH_X86DISPATCH overrides this.
3543
+ * internal macro XXH_X86DISPATCH overrides this.
3232
3544
  */
3233
3545
  enum XXH_VECTOR_TYPE /* fake enum */ {
3234
3546
  XXH_SCALAR = 0, /*!< Portable scalar version */
@@ -3240,7 +3552,11 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
3240
3552
  */
3241
3553
  XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */
3242
3554
  XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */
3243
- XXH_NEON = 4, /*!< NEON for most ARMv7-A and all AArch64 */
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
+ */
3244
3560
  XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */
3245
3561
  XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */
3246
3562
  };
@@ -3273,6 +3589,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
3273
3589
  # elif ( \
3274
3590
  defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \
3275
3591
  || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) /* msvc */ \
3592
+ || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE(<arm_neon.h>)) /* wasm simd128 via SIMDe */ \
3276
3593
  ) && ( \
3277
3594
  defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \
3278
3595
  || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
@@ -3478,6 +3795,9 @@ XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs)
3478
3795
  *
3479
3796
  * It also seems to fix some bad codegen on GCC, making it almost as fast as clang.
3480
3797
  *
3798
+ * When using WASM SIMD128, if this is 2 or 6, SIMDe will scalarize 2 of the lanes meaning
3799
+ * it effectively becomes worse 4.
3800
+ *
3481
3801
  * @see XXH3_accumulate_512_neon()
3482
3802
  */
3483
3803
  # ifndef XXH3_NEON_LANES
@@ -3623,7 +3943,6 @@ do { \
3623
3943
  } while (0)
3624
3944
  #endif /* XXH_VECTOR == XXH_SVE */
3625
3945
 
3626
-
3627
3946
  /* prefetch
3628
3947
  * can be disabled, by declaring XXH_NO_PREFETCH build macro */
3629
3948
  #if defined(XXH_NO_PREFETCH)
@@ -3668,6 +3987,8 @@ XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = {
3668
3987
  0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
3669
3988
  };
3670
3989
 
3990
+ static const xxh_u64 PRIME_MX1 = 0x165667919E3779F9ULL; /*!< 0b0001011001010110011001111001000110011110001101110111100111111001 */
3991
+ static const xxh_u64 PRIME_MX2 = 0x9FB21C651E98DF25ULL; /*!< 0b1001111110110010000111000110010100011110100110001101111100100101 */
3671
3992
 
3672
3993
  #ifdef XXH_OLD_NAMES
3673
3994
  # define kSecret XXH3_kSecret
@@ -3872,7 +4193,7 @@ XXH_FORCE_INLINE XXH_CONSTF xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
3872
4193
  static XXH64_hash_t XXH3_avalanche(xxh_u64 h64)
3873
4194
  {
3874
4195
  h64 = XXH_xorshift64(h64, 37);
3875
- h64 *= 0x165667919E3779F9ULL;
4196
+ h64 *= PRIME_MX1;
3876
4197
  h64 = XXH_xorshift64(h64, 32);
3877
4198
  return h64;
3878
4199
  }
@@ -3886,9 +4207,9 @@ static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len)
3886
4207
  {
3887
4208
  /* this mix is inspired by Pelle Evensen's rrmxmx */
3888
4209
  h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24);
3889
- h64 *= 0x9FB21C651E98DF25ULL;
4210
+ h64 *= PRIME_MX2;
3890
4211
  h64 ^= (h64 >> 35) + len ;
3891
- h64 *= 0x9FB21C651E98DF25ULL;
4212
+ h64 *= PRIME_MX2;
3892
4213
  return XXH_xorshift64(h64, 28);
3893
4214
  }
3894
4215
 
@@ -4059,7 +4380,7 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
4059
4380
  XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
4060
4381
  XXH_ASSERT(16 < len && len <= 128);
4061
4382
 
4062
- { xxh_u64 acc = len * XXH_PRIME64_1, acc_end;
4383
+ { xxh_u64 acc = len * XXH_PRIME64_1;
4063
4384
  #if XXH_SIZE_OPT >= 1
4064
4385
  /* Smaller and cleaner, but slightly slower. */
4065
4386
  unsigned int i = (unsigned int)(len - 1) / 32;
@@ -4067,25 +4388,23 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
4067
4388
  acc += XXH3_mix16B(input+16 * i, secret+32*i, seed);
4068
4389
  acc += XXH3_mix16B(input+len-16*(i+1), secret+32*i+16, seed);
4069
4390
  } while (i-- != 0);
4070
- acc_end = 0;
4071
4391
  #else
4072
- acc += XXH3_mix16B(input+0, secret+0, seed);
4073
- acc_end = XXH3_mix16B(input+len-16, secret+16, seed);
4074
4392
  if (len > 32) {
4075
- acc += XXH3_mix16B(input+16, secret+32, seed);
4076
- acc_end += XXH3_mix16B(input+len-32, secret+48, seed);
4077
4393
  if (len > 64) {
4078
- acc += XXH3_mix16B(input+32, secret+64, seed);
4079
- acc_end += XXH3_mix16B(input+len-48, secret+80, seed);
4080
-
4081
4394
  if (len > 96) {
4082
4395
  acc += XXH3_mix16B(input+48, secret+96, seed);
4083
- acc_end += XXH3_mix16B(input+len-64, secret+112, seed);
4396
+ acc += XXH3_mix16B(input+len-64, secret+112, seed);
4084
4397
  }
4398
+ acc += XXH3_mix16B(input+32, secret+64, seed);
4399
+ acc += XXH3_mix16B(input+len-48, secret+80, seed);
4085
4400
  }
4401
+ acc += XXH3_mix16B(input+16, secret+32, seed);
4402
+ acc += XXH3_mix16B(input+len-32, secret+48, seed);
4086
4403
  }
4404
+ acc += XXH3_mix16B(input+0, secret+0, seed);
4405
+ acc += XXH3_mix16B(input+len-16, secret+16, seed);
4087
4406
  #endif
4088
- return XXH3_avalanche(acc + acc_end);
4407
+ return XXH3_avalanche(acc);
4089
4408
  }
4090
4409
  }
4091
4410
 
@@ -4576,7 +4895,7 @@ XXH3_scalarScrambleRound(void* XXH_RESTRICT acc,
4576
4895
 
4577
4896
  /*!
4578
4897
  * @internal
4579
- * @brief The bulk processing loop for NEON.
4898
+ * @brief The bulk processing loop for NEON and WASM SIMD128.
4580
4899
  *
4581
4900
  * The NEON code path is actually partially scalar when running on AArch64. This
4582
4901
  * is to optimize the pipelining and can have up to 15% speedup depending on the
@@ -4593,7 +4912,11 @@ XXH3_scalarScrambleRound(void* XXH_RESTRICT acc,
4593
4912
  * Since, as stated, the most optimal amount of lanes for Cortexes is 6,
4594
4913
  * there needs to be *three* versions of the accumulate operation used
4595
4914
  * for the remaining 2 lanes.
4915
+ *
4916
+ * WASM's SIMD128 uses SIMDe's arm_neon.h polyfill because the intrinsics overlap
4917
+ * nearly perfectly.
4596
4918
  */
4919
+
4597
4920
  XXH_FORCE_INLINE void
4598
4921
  XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
4599
4922
  const void* XXH_RESTRICT input,
@@ -4604,10 +4927,30 @@ XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
4604
4927
  { /* GCC for darwin arm64 does not like aliasing here */
4605
4928
  xxh_aliasing_uint64x2_t* const xacc = (xxh_aliasing_uint64x2_t*) acc;
4606
4929
  /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */
4607
- uint8_t const* const xinput = (const uint8_t *) input;
4608
- uint8_t const* const xsecret = (const uint8_t *) secret;
4930
+ uint8_t const* xinput = (const uint8_t *) input;
4931
+ uint8_t const* xsecret = (const uint8_t *) secret;
4609
4932
 
4610
4933
  size_t i;
4934
+ #ifdef __wasm_simd128__
4935
+ /*
4936
+ * On WASM SIMD128, Clang emits direct address loads when XXH3_kSecret
4937
+ * is constant propagated, which results in it converting it to this
4938
+ * inside the loop:
4939
+ *
4940
+ * a = v128.load(XXH3_kSecret + 0 + $secret_offset, offset = 0)
4941
+ * b = v128.load(XXH3_kSecret + 16 + $secret_offset, offset = 0)
4942
+ * ...
4943
+ *
4944
+ * This requires a full 32-bit address immediate (and therefore a 6 byte
4945
+ * instruction) as well as an add for each offset.
4946
+ *
4947
+ * Putting an asm guard prevents it from folding (at the cost of losing
4948
+ * the alignment hint), and uses the free offset in `v128.load` instead
4949
+ * of adding secret_offset each time which overall reduces code size by
4950
+ * about a kilobyte and improves performance.
4951
+ */
4952
+ XXH_COMPILER_GUARD(xsecret);
4953
+ #endif
4611
4954
  /* Scalar lanes use the normal scalarRound routine */
4612
4955
  for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) {
4613
4956
  XXH3_scalarRound(acc, input, secret, i);
@@ -4634,9 +4977,9 @@ XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
4634
4977
  * get one vector with the low 32 bits of each lane, and one vector
4635
4978
  * with the high 32 bits of each lane.
4636
4979
  *
4637
- * This compiles to two instructions on AArch64 and has a paired vector
4638
- * result, which is an artifact from ARMv7a's version which modified both
4639
- * vectors in place.
4980
+ * The intrinsic returns a double vector because the original ARMv7-a
4981
+ * instruction modified both arguments in place. AArch64 and SIMD128 emit
4982
+ * two instructions from this intrinsic.
4640
4983
  *
4641
4984
  * [ dk11L | dk11H | dk12L | dk12H ] -> [ dk11L | dk12L | dk21L | dk22L ]
4642
4985
  * [ dk21L | dk21H | dk22L | dk22H ] -> [ dk11H | dk12H | dk21H | dk22H ]
@@ -4652,7 +4995,7 @@ XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
4652
4995
  /*
4653
4996
  * Then, we can split the vectors horizontally and multiply which, as for most
4654
4997
  * widening intrinsics, have a variant that works on both high half vectors
4655
- * for free on AArch64.
4998
+ * for free on AArch64. A similar instruction is available on SIMD128.
4656
4999
  *
4657
5000
  * sum = data_swap + (u64x2) data_key_lo * (u64x2) data_key_hi
4658
5001
  */
@@ -4670,8 +5013,8 @@ XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
4670
5013
  * for reasons likely related to umlal being limited to certain NEON
4671
5014
  * pipelines, this is worse. A compiler guard fixes this.
4672
5015
  */
4673
- XXH_COMPILER_GUARD_W(sum_1);
4674
- XXH_COMPILER_GUARD_W(sum_2);
5016
+ XXH_COMPILER_GUARD_CLANG_NEON(sum_1);
5017
+ XXH_COMPILER_GUARD_CLANG_NEON(sum_2);
4675
5018
  /* xacc[i] = acc_vec + sum; */
4676
5019
  xacc[i] = vaddq_u64(xacc[i], sum_1);
4677
5020
  xacc[i+1] = vaddq_u64(xacc[i+1], sum_2);
@@ -4694,7 +5037,7 @@ XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
4694
5037
  /* sum = data_swap + (u64x2) data_key_lo * (u64x2) data_key_hi; */
4695
5038
  uint64x2_t sum = vmlal_u32(data_swap, data_key_lo, data_key_hi);
4696
5039
  /* Same Clang workaround as before */
4697
- XXH_COMPILER_GUARD_W(sum);
5040
+ XXH_COMPILER_GUARD_CLANG_NEON(sum);
4698
5041
  /* xacc[i] = acc_vec + sum; */
4699
5042
  xacc[i] = vaddq_u64 (xacc[i], sum);
4700
5043
  }
@@ -4709,9 +5052,16 @@ XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
4709
5052
 
4710
5053
  { xxh_aliasing_uint64x2_t* xacc = (xxh_aliasing_uint64x2_t*) acc;
4711
5054
  uint8_t const* xsecret = (uint8_t const*) secret;
4712
- uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1);
4713
5055
 
4714
5056
  size_t i;
5057
+ /* WASM uses operator overloads and doesn't need these. */
5058
+ #ifndef __wasm_simd128__
5059
+ /* { prime32_1, prime32_1 } */
5060
+ uint32x2_t const kPrimeLo = vdup_n_u32(XXH_PRIME32_1);
5061
+ /* { 0, prime32_1, 0, prime32_1 } */
5062
+ uint32x4_t const kPrimeHi = vreinterpretq_u32_u64(vdupq_n_u64((xxh_u64)XXH_PRIME32_1 << 32));
5063
+ #endif
5064
+
4715
5065
  /* AArch64 uses both scalar and neon at the same time */
4716
5066
  for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) {
4717
5067
  XXH3_scalarScrambleRound(acc, secret, i);
@@ -4725,33 +5075,28 @@ XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
4725
5075
  /* xacc[i] ^= xsecret[i]; */
4726
5076
  uint64x2_t key_vec = XXH_vld1q_u64(xsecret + (i * 16));
4727
5077
  uint64x2_t data_key = veorq_u64(data_vec, key_vec);
4728
-
4729
5078
  /* xacc[i] *= XXH_PRIME32_1 */
4730
- uint32x2_t data_key_lo = vmovn_u64(data_key);
4731
- uint32x2_t data_key_hi = vshrn_n_u64(data_key, 32);
5079
+ #ifdef __wasm_simd128__
5080
+ /* SIMD128 has multiply by u64x2, use it instead of expanding and scalarizing */
5081
+ xacc[i] = data_key * XXH_PRIME32_1;
5082
+ #else
4732
5083
  /*
4733
- * prod_hi = (data_key >> 32) * XXH_PRIME32_1;
5084
+ * Expanded version with portable NEON intrinsics
4734
5085
  *
4735
- * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will
4736
- * incorrectly "optimize" this:
4737
- * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b));
4738
- * shifted = vshll_n_u32(tmp, 32);
4739
- * to this:
4740
- * tmp = "vmulq_u64"(a, b); // no such thing!
4741
- * shifted = vshlq_n_u64(tmp, 32);
5086
+ * lo(x) * lo(y) + (hi(x) * lo(y) << 32)
4742
5087
  *
4743
- * However, unlike SSE, Clang lacks a 64-bit multiply routine
4744
- * for NEON, and it scalarizes two 64-bit multiplies instead.
5088
+ * prod_hi = hi(data_key) * lo(prime) << 32
4745
5089
  *
4746
- * vmull_u32 has the same timing as vmul_u32, and it avoids
4747
- * this bug completely.
4748
- * See https://bugs.llvm.org/show_bug.cgi?id=39967
5090
+ * Since we only need 32 bits of this multiply a trick can be used, reinterpreting the vector
5091
+ * as a uint32x4_t and multiplying by { 0, prime, 0, prime } to cancel out the unwanted bits
5092
+ * and avoid the shift.
4749
5093
  */
4750
- uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime);
4751
- /* xacc[i] = prod_hi << 32; */
4752
- prod_hi = vshlq_n_u64(prod_hi, 32);
4753
- /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */
4754
- xacc[i] = vmlal_u32(prod_hi, data_key_lo, prime);
5094
+ uint32x4_t prod_hi = vmulq_u32 (vreinterpretq_u32_u64(data_key), kPrimeHi);
5095
+ /* Extract low bits for vmlal_u32 */
5096
+ uint32x2_t data_key_lo = vmovn_u64(data_key);
5097
+ /* xacc[i] = prod_hi + lo(data_key) * XXH_PRIME32_1; */
5098
+ xacc[i] = vmlal_u32(vreinterpretq_u64_u32(prod_hi), data_key_lo, kPrimeLo);
5099
+ #endif
4755
5100
  }
4756
5101
  }
4757
5102
  }
@@ -5467,6 +5812,12 @@ static void XXH_alignedFree(void* p)
5467
5812
  }
5468
5813
  }
5469
5814
  /*! @ingroup XXH3_family */
5815
+ /*!
5816
+ * @brief Allocate an @ref XXH3_state_t.
5817
+ *
5818
+ * Must be freed with XXH3_freeState().
5819
+ * @return An allocated XXH3_state_t on success, `NULL` on failure.
5820
+ */
5470
5821
  XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
5471
5822
  {
5472
5823
  XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64);
@@ -5476,6 +5827,13 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
5476
5827
  }
5477
5828
 
5478
5829
  /*! @ingroup XXH3_family */
5830
+ /*!
5831
+ * @brief Frees an @ref XXH3_state_t.
5832
+ *
5833
+ * Must be allocated with XXH3_createState().
5834
+ * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState().
5835
+ * @return XXH_OK.
5836
+ */
5479
5837
  XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr)
5480
5838
  {
5481
5839
  XXH_alignedFree(statePtr);
@@ -5832,7 +6190,7 @@ XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_
5832
6190
  m128.low64 ^= (m128.high64 >> 3);
5833
6191
 
5834
6192
  m128.low64 = XXH_xorshift64(m128.low64, 35);
5835
- m128.low64 *= 0x9FB21C651E98DF25ULL;
6193
+ m128.low64 *= PRIME_MX2;
5836
6194
  m128.low64 = XXH_xorshift64(m128.low64, 28);
5837
6195
  m128.high64 = XXH3_avalanche(m128.high64);
5838
6196
  return m128;
@@ -2,6 +2,6 @@ require 'digest'
2
2
 
3
3
  module Digest
4
4
  class XXHash < Digest::Class
5
- VERSION = "0.2.6"
5
+ VERSION = "0.2.7"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: digest-xxhash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - konsolebox
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-22 00:00:00.000000000 Z
11
+ date: 2023-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -30,32 +30,20 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.0'
34
- - - "!="
35
- - !ruby/object:Gem::Version
36
- version: 1.1.3
37
- - - "!="
38
- - !ruby/object:Gem::Version
39
- version: 1.1.4
40
- - - "!="
33
+ version: '1.2'
34
+ - - ">="
41
35
  - !ruby/object:Gem::Version
42
- version: 1.1.5
36
+ version: 1.2.3
43
37
  type: :development
44
38
  prerelease: false
45
39
  version_requirements: !ruby/object:Gem::Requirement
46
40
  requirements:
47
41
  - - "~>"
48
42
  - !ruby/object:Gem::Version
49
- version: '1.0'
50
- - - "!="
51
- - !ruby/object:Gem::Version
52
- version: 1.1.3
53
- - - "!="
54
- - !ruby/object:Gem::Version
55
- version: 1.1.4
56
- - - "!="
43
+ version: '1.2'
44
+ - - ">="
57
45
  - !ruby/object:Gem::Version
58
- version: 1.1.5
46
+ version: 1.2.3
59
47
  - !ruby/object:Gem::Dependency
60
48
  name: minitest
61
49
  requirement: !ruby/object:Gem::Requirement
@@ -117,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
105
  - !ruby/object:Gem::Version
118
106
  version: '0'
119
107
  requirements: []
120
- rubygems_version: 3.4.10
108
+ rubygems_version: 3.4.14
121
109
  signing_key:
122
110
  specification_version: 4
123
111
  summary: A Digest framework based XXHash library for Ruby