digest-xxhash 0.2.2 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,49 +32,142 @@
32
32
  * - xxHash homepage: https://www.xxhash.com
33
33
  * - xxHash source repository: https://github.com/Cyan4973/xxHash
34
34
  */
35
+
35
36
  /*!
36
37
  * @mainpage xxHash
37
38
  *
39
+ * xxHash is an extremely fast non-cryptographic hash algorithm, working at RAM speed
40
+ * limits.
41
+ *
42
+ * It is proposed in four flavors, in three families:
43
+ * 1. @ref XXH32_family
44
+ * - Classic 32-bit hash function. Simple, compact, and runs on almost all
45
+ * 32-bit and 64-bit systems.
46
+ * 2. @ref XXH64_family
47
+ * - Classic 64-bit adaptation of XXH32. Just as simple, and runs well on most
48
+ * 64-bit systems (but _not_ 32-bit systems).
49
+ * 3. @ref XXH3_family
50
+ * - Modern 64-bit and 128-bit hash function family which features improved
51
+ * strength and performance across the board, especially on smaller data.
52
+ * It benefits greatly from SIMD and 64-bit without requiring it.
53
+ *
54
+ * Benchmarks
55
+ * ---
56
+ * The reference system uses an Intel i7-9700K CPU, and runs Ubuntu x64 20.04.
57
+ * The open source benchmark program is compiled with clang v10.0 using -O3 flag.
58
+ *
59
+ * | Hash Name | ISA ext | Width | Large Data Speed | Small Data Velocity |
60
+ * | -------------------- | ------- | ----: | ---------------: | ------------------: |
61
+ * | XXH3_64bits() | @b AVX2 | 64 | 59.4 GB/s | 133.1 |
62
+ * | MeowHash | AES-NI | 128 | 58.2 GB/s | 52.5 |
63
+ * | XXH3_128bits() | @b AVX2 | 128 | 57.9 GB/s | 118.1 |
64
+ * | CLHash | PCLMUL | 64 | 37.1 GB/s | 58.1 |
65
+ * | XXH3_64bits() | @b SSE2 | 64 | 31.5 GB/s | 133.1 |
66
+ * | XXH3_128bits() | @b SSE2 | 128 | 29.6 GB/s | 118.1 |
67
+ * | RAM sequential read | | N/A | 28.0 GB/s | N/A |
68
+ * | ahash | AES-NI | 64 | 22.5 GB/s | 107.2 |
69
+ * | City64 | | 64 | 22.0 GB/s | 76.6 |
70
+ * | T1ha2 | | 64 | 22.0 GB/s | 99.0 |
71
+ * | City128 | | 128 | 21.7 GB/s | 57.7 |
72
+ * | FarmHash | AES-NI | 64 | 21.3 GB/s | 71.9 |
73
+ * | XXH64() | | 64 | 19.4 GB/s | 71.0 |
74
+ * | SpookyHash | | 64 | 19.3 GB/s | 53.2 |
75
+ * | Mum | | 64 | 18.0 GB/s | 67.0 |
76
+ * | CRC32C | SSE4.2 | 32 | 13.0 GB/s | 57.9 |
77
+ * | XXH32() | | 32 | 9.7 GB/s | 71.9 |
78
+ * | City32 | | 32 | 9.1 GB/s | 66.0 |
79
+ * | Blake3* | @b AVX2 | 256 | 4.4 GB/s | 8.1 |
80
+ * | Murmur3 | | 32 | 3.9 GB/s | 56.1 |
81
+ * | SipHash* | | 64 | 3.0 GB/s | 43.2 |
82
+ * | Blake3* | @b SSE2 | 256 | 2.4 GB/s | 8.1 |
83
+ * | HighwayHash | | 64 | 1.4 GB/s | 6.0 |
84
+ * | FNV64 | | 64 | 1.2 GB/s | 62.7 |
85
+ * | Blake2* | | 256 | 1.1 GB/s | 5.1 |
86
+ * | SHA1* | | 160 | 0.8 GB/s | 5.6 |
87
+ * | MD5* | | 128 | 0.6 GB/s | 7.8 |
88
+ * @note
89
+ * - Hashes which require a specific ISA extension are noted. SSE2 is also noted,
90
+ * even though it is mandatory on x64.
91
+ * - Hashes with an asterisk are cryptographic. Note that MD5 is non-cryptographic
92
+ * by modern standards.
93
+ * - Small data velocity is a rough average of algorithm's efficiency for small
94
+ * data. For more accurate information, see the wiki.
95
+ * - More benchmarks and strength tests are found on the wiki:
96
+ * https://github.com/Cyan4973/xxHash/wiki
97
+ *
98
+ * Usage
99
+ * ------
100
+ * All xxHash variants use a similar API. Changing the algorithm is a trivial
101
+ * substitution.
102
+ *
103
+ * @pre
104
+ * For functions which take an input and length parameter, the following
105
+ * requirements are assumed:
106
+ * - The range from [`input`, `input + length`) is valid, readable memory.
107
+ * - The only exception is if the `length` is `0`, `input` may be `NULL`.
108
+ * - For C++, the objects must have the *TriviallyCopyable* property, as the
109
+ * functions access bytes directly as if it was an array of `unsigned char`.
110
+ *
111
+ * @anchor single_shot_example
112
+ * **Single Shot**
113
+ *
114
+ * These functions are stateless functions which hash a contiguous block of memory,
115
+ * immediately returning the result. They are the easiest and usually the fastest
116
+ * option.
117
+ *
118
+ * XXH32(), XXH64(), XXH3_64bits(), XXH3_128bits()
119
+ *
120
+ * @code{.c}
121
+ * #include <string.h>
122
+ * #include "xxhash.h"
123
+ *
124
+ * // Example for a function which hashes a null terminated string with XXH32().
125
+ * XXH32_hash_t hash_string(const char* string, XXH32_hash_t seed)
126
+ * {
127
+ * // NULL pointers are only valid if the length is zero
128
+ * size_t length = (string == NULL) ? 0 : strlen(string);
129
+ * return XXH32(string, length, seed);
130
+ * }
131
+ * @endcode
132
+ *
133
+ * @anchor streaming_example
134
+ * **Streaming**
135
+ *
136
+ * These groups of functions allow incremental hashing of unknown size, even
137
+ * more than what would fit in a size_t.
138
+ *
139
+ * XXH32_reset(), XXH64_reset(), XXH3_64bits_reset(), XXH3_128bits_reset()
140
+ *
141
+ * @code{.c}
142
+ * #include <stdio.h>
143
+ * #include <assert.h>
144
+ * #include "xxhash.h"
145
+ * // Example for a function which hashes a FILE incrementally with XXH3_64bits().
146
+ * XXH64_hash_t hashFile(FILE* f)
147
+ * {
148
+ * // Allocate a state struct. Do not just use malloc() or new.
149
+ * XXH3_state_t* state = XXH3_createState();
150
+ * assert(state != NULL && "Out of memory!");
151
+ * // Reset the state to start a new hashing session.
152
+ * XXH3_64bits_reset(state);
153
+ * char buffer[4096];
154
+ * size_t count;
155
+ * // Read the file in chunks
156
+ * while ((count = fread(buffer, 1, sizeof(buffer), f)) != 0) {
157
+ * // Run update() as many times as necessary to process the data
158
+ * XXH3_64bits_update(state, buffer, count);
159
+ * }
160
+ * // Retrieve the finalized hash. This will not change the state.
161
+ * XXH64_hash_t result = XXH3_64bits_digest(state);
162
+ * // Free the state. Do not use free().
163
+ * XXH3_freeState(state);
164
+ * return result;
165
+ * }
166
+ * @endcode
167
+ *
38
168
  * @file xxhash.h
39
169
  * xxHash prototypes and implementation
40
170
  */
41
- /* TODO: update */
42
- /* Notice extracted from xxHash homepage:
43
-
44
- xxHash is an extremely fast hash algorithm, running at RAM speed limits.
45
- It also successfully passes all tests from the SMHasher suite.
46
-
47
- Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
48
-
49
- Name Speed Q.Score Author
50
- xxHash 5.4 GB/s 10
51
- CrapWow 3.2 GB/s 2 Andrew
52
- MurmurHash 3a 2.7 GB/s 10 Austin Appleby
53
- SpookyHash 2.0 GB/s 10 Bob Jenkins
54
- SBox 1.4 GB/s 9 Bret Mulvey
55
- Lookup3 1.2 GB/s 9 Bob Jenkins
56
- SuperFastHash 1.2 GB/s 1 Paul Hsieh
57
- CityHash64 1.05 GB/s 10 Pike & Alakuijala
58
- FNV 0.55 GB/s 5 Fowler, Noll, Vo
59
- CRC32 0.43 GB/s 9
60
- MD5-32 0.33 GB/s 10 Ronald L. Rivest
61
- SHA1-32 0.28 GB/s 10
62
-
63
- Q.Score is a measure of quality of the hash function.
64
- It depends on successfully passing SMHasher test set.
65
- 10 is a perfect score.
66
-
67
- Note: SMHasher's CRC32 implementation is not the fastest one.
68
- Other speed-oriented implementations can be faster,
69
- especially in combination with PCLMUL instruction:
70
- https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735
71
-
72
- A 64-bit version, named XXH64, is available since r35.
73
- It offers much better speed, but for 64-bit applications only.
74
- Name Speed on 64 bits Speed on 32 bits
75
- XXH64 13.8 GB/s 1.9 GB/s
76
- XXH32 6.8 GB/s 6.0 GB/s
77
- */
78
171
 
79
172
  #if defined (__cplusplus)
80
173
  extern "C" {
@@ -84,21 +177,53 @@ extern "C" {
84
177
  * INLINE mode
85
178
  ******************************/
86
179
  /*!
87
- * XXH_INLINE_ALL (and XXH_PRIVATE_API)
180
+ * @defgroup public Public API
181
+ * Contains details on the public xxHash functions.
182
+ * @{
183
+ */
184
+ #ifdef XXH_DOXYGEN
185
+ /*!
186
+ * @brief Exposes the implementation and marks all functions as `inline`.
187
+ *
88
188
  * Use these build macros to inline xxhash into the target unit.
89
189
  * Inlining improves performance on small inputs, especially when the length is
90
190
  * expressed as a compile-time constant:
91
191
  *
92
- * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html
192
+ * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html
93
193
  *
94
194
  * It also keeps xxHash symbols private to the unit, so they are not exported.
95
195
  *
96
196
  * Usage:
197
+ * @code{.c}
97
198
  * #define XXH_INLINE_ALL
98
199
  * #include "xxhash.h"
99
- *
200
+ * @endcode
100
201
  * Do not compile and link xxhash.o as a separate object, as it is not useful.
101
202
  */
203
+ # define XXH_INLINE_ALL
204
+ # undef XXH_INLINE_ALL
205
+ /*!
206
+ * @brief Exposes the implementation without marking functions as inline.
207
+ */
208
+ # define XXH_PRIVATE_API
209
+ # undef XXH_PRIVATE_API
210
+ /*!
211
+ * @brief Emulate a namespace by transparently prefixing all symbols.
212
+ *
213
+ * If you want to include _and expose_ xxHash functions from within your own
214
+ * library, but also want to avoid symbol collisions with other libraries which
215
+ * may also include xxHash, you can use @ref XXH_NAMESPACE to automatically prefix
216
+ * any public symbol from xxhash library with the value of @ref XXH_NAMESPACE
217
+ * (therefore, avoid empty or numeric values).
218
+ *
219
+ * Note that no change is required within the calling program as long as it
220
+ * includes `xxhash.h`: Regular symbol names will be automatically translated
221
+ * by this header.
222
+ */
223
+ # define XXH_NAMESPACE /* YOUR NAME HERE */
224
+ # undef XXH_NAMESPACE
225
+ #endif
226
+
102
227
  #if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \
103
228
  && !defined(XXH_INLINE_ALL_31684351384)
104
229
  /* this section should be traversed only once */
@@ -213,21 +338,13 @@ extern "C" {
213
338
  # undef XXHASH_H_STATIC_13879238742
214
339
  #endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */
215
340
 
216
-
217
-
218
341
  /* ****************************************************************
219
342
  * Stable API
220
343
  *****************************************************************/
221
344
  #ifndef XXHASH_H_5627135585666179
222
345
  #define XXHASH_H_5627135585666179 1
223
346
 
224
-
225
- /*!
226
- * @defgroup public Public API
227
- * Contains details on the public xxHash functions.
228
- * @{
229
- */
230
- /* specific declaration modes for Windows */
347
+ /*! @brief Marks a global symbol. */
231
348
  #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
232
349
  # if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
233
350
  # ifdef XXH_EXPORT
@@ -240,24 +357,6 @@ extern "C" {
240
357
  # endif
241
358
  #endif
242
359
 
243
- #ifdef XXH_DOXYGEN
244
- /*!
245
- * @brief Emulate a namespace by transparently prefixing all symbols.
246
- *
247
- * If you want to include _and expose_ xxHash functions from within your own
248
- * library, but also want to avoid symbol collisions with other libraries which
249
- * may also include xxHash, you can use XXH_NAMESPACE to automatically prefix
250
- * any public symbol from xxhash library with the value of XXH_NAMESPACE
251
- * (therefore, avoid empty or numeric values).
252
- *
253
- * Note that no change is required within the calling program as long as it
254
- * includes `xxhash.h`: Regular symbol names will be automatically translated
255
- * by this header.
256
- */
257
- # define XXH_NAMESPACE /* YOUR NAME HERE */
258
- # undef XXH_NAMESPACE
259
- #endif
260
-
261
360
  #ifdef XXH_NAMESPACE
262
361
  # define XXH_CAT(A,B) A##B
263
362
  # define XXH_NAME2(A,B) XXH_CAT(A,B)
@@ -317,12 +416,40 @@ extern "C" {
317
416
  #endif
318
417
 
319
418
 
419
+ /* *************************************
420
+ * Compiler specifics
421
+ ***************************************/
422
+
423
+ /* specific declaration modes for Windows */
424
+ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
425
+ # if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
426
+ # ifdef XXH_EXPORT
427
+ # define XXH_PUBLIC_API __declspec(dllexport)
428
+ # elif XXH_IMPORT
429
+ # define XXH_PUBLIC_API __declspec(dllimport)
430
+ # endif
431
+ # else
432
+ # define XXH_PUBLIC_API /* do nothing */
433
+ # endif
434
+ #endif
435
+
436
+ #if defined (__GNUC__)
437
+ # define XXH_CONSTF __attribute__((const))
438
+ # define XXH_PUREF __attribute__((pure))
439
+ # define XXH_MALLOCF __attribute__((malloc))
440
+ #else
441
+ # define XXH_CONSTF /* disable */
442
+ # define XXH_PUREF
443
+ # define XXH_MALLOCF
444
+ #endif
445
+
320
446
  /* *************************************
321
447
  * Version
322
448
  ***************************************/
323
449
  #define XXH_VERSION_MAJOR 0
324
450
  #define XXH_VERSION_MINOR 8
325
451
  #define XXH_VERSION_RELEASE 1
452
+ /*! @brief Version number, encoded as two digits each */
326
453
  #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
327
454
 
328
455
  /*!
@@ -331,16 +458,22 @@ extern "C" {
331
458
  * This is mostly useful when xxHash is compiled as a shared library,
332
459
  * since the returned value comes from the library, as opposed to header file.
333
460
  *
334
- * @return `XXH_VERSION_NUMBER` of the invoked library.
461
+ * @return @ref XXH_VERSION_NUMBER of the invoked library.
335
462
  */
336
- XXH_PUBLIC_API unsigned XXH_versionNumber (void);
463
+ XXH_PUBLIC_API XXH_CONSTF unsigned XXH_versionNumber (void);
337
464
 
338
465
 
339
466
  /* ****************************
340
467
  * Common basic types
341
468
  ******************************/
342
469
  #include <stddef.h> /* size_t */
343
- typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
470
+ /*!
471
+ * @brief Exit code for the streaming API.
472
+ */
473
+ typedef enum {
474
+ XXH_OK = 0, /*!< OK */
475
+ XXH_ERROR /*!< Error */
476
+ } XXH_errorcode;
344
477
 
345
478
 
346
479
  /*-**********************************************************************
@@ -364,29 +497,27 @@ typedef uint32_t XXH32_hash_t;
364
497
  # include <limits.h>
365
498
  # if UINT_MAX == 0xFFFFFFFFUL
366
499
  typedef unsigned int XXH32_hash_t;
500
+ # elif ULONG_MAX == 0xFFFFFFFFUL
501
+ typedef unsigned long XXH32_hash_t;
367
502
  # else
368
- # if ULONG_MAX == 0xFFFFFFFFUL
369
- typedef unsigned long XXH32_hash_t;
370
- # else
371
- # error "unsupported platform: need a 32-bit type"
372
- # endif
503
+ # error "unsupported platform: need a 32-bit type"
373
504
  # endif
374
505
  #endif
375
506
 
376
507
  /*!
377
508
  * @}
378
509
  *
379
- * @defgroup xxh32_family XXH32 family
510
+ * @defgroup XXH32_family XXH32 family
380
511
  * @ingroup public
381
512
  * Contains functions used in the classic 32-bit xxHash algorithm.
382
513
  *
383
514
  * @note
384
515
  * XXH32 is useful for older platforms, with no or poor 64-bit performance.
385
- * Note that @ref xxh3_family provides competitive speed
386
- * for both 32-bit and 64-bit systems, and offers true 64/128 bit hash results.
516
+ * Note that the @ref XXH3_family provides competitive speed for both 32-bit
517
+ * and 64-bit systems, and offers true 64/128 bit hash results.
387
518
  *
388
- * @see @ref xxh64_family, @ref xxh3_family : Other xxHash families
389
- * @see @ref xxh32_impl for implementation details
519
+ * @see @ref XXH64_family, @ref XXH3_family : Other xxHash families
520
+ * @see @ref XXH32_impl for implementation details
390
521
  * @{
391
522
  */
392
523
 
@@ -395,6 +526,8 @@ typedef uint32_t XXH32_hash_t;
395
526
  *
396
527
  * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s
397
528
  *
529
+ * See @ref single_shot_example "Single Shot Example" for an example.
530
+ *
398
531
  * @param input The block of data to be hashed, at least @p length bytes in size.
399
532
  * @param length The length of @p input, in bytes.
400
533
  * @param seed The 32-bit seed to alter the hash's output predictably.
@@ -412,8 +545,9 @@ typedef uint32_t XXH32_hash_t;
412
545
  * @see
413
546
  * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version.
414
547
  */
415
- XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed);
548
+ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed);
416
549
 
550
+ #ifndef XXH_NO_STREAM
417
551
  /*!
418
552
  * Streaming functions generate the xxHash value from an incremental input.
419
553
  * This method is slower than single-call functions, due to state management.
@@ -436,32 +570,7 @@ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_
436
570
  *
437
571
  * When done, release the state using `XXH*_freeState()`.
438
572
  *
439
- * Example code for incrementally hashing a file:
440
- * @code{.c}
441
- * #include <stdio.h>
442
- * #include <xxhash.h>
443
- * #define BUFFER_SIZE 256
444
- *
445
- * // Note: XXH64 and XXH3 use the same interface.
446
- * XXH32_hash_t
447
- * hashFile(FILE* stream)
448
- * {
449
- * XXH32_state_t* state;
450
- * unsigned char buf[BUFFER_SIZE];
451
- * size_t amt;
452
- * XXH32_hash_t hash;
453
- *
454
- * state = XXH32_createState(); // Create a state
455
- * assert(state != NULL); // Error check here
456
- * XXH32_reset(state, 0xbaad5eed); // Reset state with our seed
457
- * while ((amt = fread(buf, 1, sizeof(buf), stream)) != 0) {
458
- * XXH32_update(state, buf, amt); // Hash the file in chunks
459
- * }
460
- * hash = XXH32_digest(state); // Finalize the hash
461
- * XXH32_freeState(state); // Clean up
462
- * return hash;
463
- * }
464
- * @endcode
573
+ * @see streaming_example at the top of @ref xxhash.h for an example.
465
574
  */
466
575
 
467
576
  /*!
@@ -478,7 +587,7 @@ typedef struct XXH32_state_s XXH32_state_t;
478
587
  * Must be freed with XXH32_freeState().
479
588
  * @return An allocated XXH32_state_t on success, `NULL` on failure.
480
589
  */
481
- XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
590
+ XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void);
482
591
  /*!
483
592
  * @brief Frees an @ref XXH32_state_t.
484
593
  *
@@ -546,7 +655,8 @@ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void*
546
655
  *
547
656
  * @return The calculated xxHash32 value from that state.
548
657
  */
549
- XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
658
+ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
659
+ #endif /* !XXH_NO_STREAM */
550
660
 
551
661
  /******* Canonical representation *******/
552
662
 
@@ -597,7 +707,7 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t
597
707
  *
598
708
  * @return The converted hash.
599
709
  */
600
- XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
710
+ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
601
711
 
602
712
 
603
713
  #ifdef __has_attribute
@@ -620,19 +730,17 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src
620
730
  #endif
621
731
 
622
732
  /*
623
- Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute
624
- introduced in CPP17 and C23.
625
- CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough
626
- C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough
627
- */
628
- #if XXH_HAS_C_ATTRIBUTE(x)
629
- # define XXH_FALLTHROUGH [[fallthrough]]
630
- #elif XXH_HAS_CPP_ATTRIBUTE(x)
733
+ * Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute
734
+ * introduced in CPP17 and C23.
735
+ * CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough
736
+ * C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough
737
+ */
738
+ #if XXH_HAS_C_ATTRIBUTE(fallthrough) || XXH_HAS_CPP_ATTRIBUTE(fallthrough)
631
739
  # define XXH_FALLTHROUGH [[fallthrough]]
632
740
  #elif XXH_HAS_ATTRIBUTE(__fallthrough__)
633
- # define XXH_FALLTHROUGH __attribute__ ((fallthrough))
741
+ # define XXH_FALLTHROUGH __attribute__ ((__fallthrough__))
634
742
  #else
635
- # define XXH_FALLTHROUGH
743
+ # define XXH_FALLTHROUGH /* fallthrough */
636
744
  #endif
637
745
 
638
746
  /*!
@@ -671,7 +779,7 @@ typedef uint64_t XXH64_hash_t;
671
779
  /*!
672
780
  * @}
673
781
  *
674
- * @defgroup xxh64_family XXH64 family
782
+ * @defgroup XXH64_family XXH64 family
675
783
  * @ingroup public
676
784
  * @{
677
785
  * Contains functions used in the classic 64-bit xxHash algorithm.
@@ -682,7 +790,6 @@ typedef uint64_t XXH64_hash_t;
682
790
  * It provides better speed for systems with vector processing capabilities.
683
791
  */
684
792
 
685
-
686
793
  /*!
687
794
  * @brief Calculates the 64-bit hash of @p input using xxHash64.
688
795
  *
@@ -706,34 +813,35 @@ typedef uint64_t XXH64_hash_t;
706
813
  * @see
707
814
  * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version.
708
815
  */
709
- XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed);
816
+ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed);
710
817
 
711
818
  /******* Streaming *******/
819
+ #ifndef XXH_NO_STREAM
712
820
  /*!
713
821
  * @brief The opaque state struct for the XXH64 streaming API.
714
822
  *
715
823
  * @see XXH64_state_s for details.
716
824
  */
717
825
  typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
718
- XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
826
+ XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void);
719
827
  XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
720
828
  XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
721
829
 
722
830
  XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed);
723
831
  XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
724
- XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
725
-
832
+ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
833
+ #endif /* !XXH_NO_STREAM */
726
834
  /******* Canonical representation *******/
727
835
  typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t;
728
836
  XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
729
- XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
837
+ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
730
838
 
731
839
  #ifndef XXH_NO_XXH3
732
840
 
733
841
  /*!
734
842
  * @}
735
843
  * ************************************************************************
736
- * @defgroup xxh3_family XXH3 family
844
+ * @defgroup XXH3_family XXH3 family
737
845
  * @ingroup public
738
846
  * @{
739
847
  *
@@ -753,12 +861,14 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src
753
861
  *
754
862
  * XXH3's speed benefits greatly from SIMD and 64-bit arithmetic,
755
863
  * but does not require it.
756
- * Any 32-bit and 64-bit targets that can run XXH32 smoothly
757
- * can run XXH3 at competitive speeds, even without vector support.
758
- * Further details are explained in the implementation.
864
+ * Most 32-bit and 64-bit targets that can run XXH32 smoothly can run XXH3
865
+ * at competitive speeds, even without vector support. Further details are
866
+ * explained in the implementation.
759
867
  *
760
868
  * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8,
761
- * ZVector and scalar targets. This can be controlled via the XXH_VECTOR macro.
869
+ * ZVector and scalar targets. This can be controlled via the @ref XXH_VECTOR
870
+ * macro. For the x86 family, an automatic dispatcher is included separately
871
+ * in @ref xxh_x86dispatch.c.
762
872
  *
763
873
  * XXH3 implementation is portable:
764
874
  * it has a generic C90 formulation that can be compiled on any platform,
@@ -774,24 +884,42 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src
774
884
  *
775
885
  * The API supports one-shot hashing, streaming mode, and custom secrets.
776
886
  */
777
-
778
887
  /*-**********************************************************************
779
888
  * XXH3 64-bit variant
780
889
  ************************************************************************/
781
890
 
782
- /* XXH3_64bits():
783
- * default 64-bit variant, using default secret and default seed of 0.
784
- * It's the fastest variant. */
785
- XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len);
891
+ /*!
892
+ * @brief 64-bit unseeded variant of XXH3.
893
+ *
894
+ * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of 0, however
895
+ * it may have slightly better performance due to constant propagation of the
896
+ * defaults.
897
+ *
898
+ * @see
899
+ * XXH32(), XXH64(), XXH3_128bits(): equivalent for the other xxHash algorithms
900
+ * @see
901
+ * XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants
902
+ * @see
903
+ * XXH3_64bits_reset(), XXH3_64bits_update(), XXH3_64bits_digest(): Streaming version.
904
+ */
905
+ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(const void* input, size_t length);
786
906
 
787
- /*
788
- * XXH3_64bits_withSeed():
789
- * This variant generates a custom secret on the fly
790
- * based on default secret altered using the `seed` value.
907
+ /*!
908
+ * @brief 64-bit seeded variant of XXH3
909
+ *
910
+ * This variant generates a custom secret on the fly based on default secret
911
+ * altered using the `seed` value.
912
+ *
791
913
  * While this operation is decently fast, note that it's not completely free.
792
- * Note: seed==0 produces the same results as XXH3_64bits().
914
+ *
915
+ * @note
916
+ * seed == 0 produces the same results as @ref XXH3_64bits().
917
+ *
918
+ * @param input The data to hash
919
+ * @param length The length
920
+ * @param seed The 64-bit seed to alter the state.
793
921
  */
794
- XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
922
+ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(const void* input, size_t length, XXH64_hash_t seed);
795
923
 
796
924
  /*!
797
925
  * The bare minimum size for a custom secret.
@@ -802,8 +930,9 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X
802
930
  */
803
931
  #define XXH3_SECRET_SIZE_MIN 136
804
932
 
805
- /*
806
- * XXH3_64bits_withSecret():
933
+ /*!
934
+ * @brief 64-bit variant of XXH3 with a custom "secret".
935
+ *
807
936
  * It's possible to provide any blob of bytes as a "secret" to generate the hash.
808
937
  * This makes it more difficult for an external actor to prepare an intentional collision.
809
938
  * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN).
@@ -819,10 +948,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X
819
948
  * This is not necessarily the case when using the blob of bytes directly
820
949
  * because, when hashing _small_ inputs, only a portion of the secret is employed.
821
950
  */
822
- XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
951
+ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
823
952
 
824
953
 
825
954
  /******* Streaming *******/
955
+ #ifndef XXH_NO_STREAM
826
956
  /*
827
957
  * Streaming requires state maintenance.
828
958
  * This operation costs memory and CPU.
@@ -836,7 +966,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len,
836
966
  * @see XXH3_state_s for details.
837
967
  */
838
968
  typedef struct XXH3_state_s XXH3_state_t;
839
- XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void);
969
+ XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void);
840
970
  XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr);
841
971
  XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state);
842
972
 
@@ -852,7 +982,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr);
852
982
  * digest will be equivalent to `XXH3_64bits_withSeed()`.
853
983
  */
854
984
  XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
855
- /*
985
+ /*!
856
986
  * XXH3_64bits_reset_withSecret():
857
987
  * `secret` is referenced, it _must outlive_ the hash streaming session.
858
988
  * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`,
@@ -864,7 +994,8 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr,
864
994
  XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
865
995
 
866
996
  XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
867
- XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr);
997
+ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr);
998
+ #endif /* !XXH_NO_STREAM */
868
999
 
869
1000
  /* note : canonical representation of XXH3 is the same as XXH64
870
1001
  * since they both produce XXH64_hash_t values */
@@ -885,11 +1016,31 @@ typedef struct {
885
1016
  XXH64_hash_t high64; /*!< `value >> 64` */
886
1017
  } XXH128_hash_t;
887
1018
 
888
- XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len);
889
- XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
890
- XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
1019
+ /*!
1020
+ * @brief Unseeded 128-bit variant of XXH3
1021
+ *
1022
+ * The 128-bit variant of XXH3 has more strength, but it has a bit of overhead
1023
+ * for shorter inputs.
1024
+ *
1025
+ * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of 0, however
1026
+ * it may have slightly better performance due to constant propagation of the
1027
+ * defaults.
1028
+ *
1029
+ * @see
1030
+ * XXH32(), XXH64(), XXH3_64bits(): equivalent for the other xxHash algorithms
1031
+ * @see
1032
+ * XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants
1033
+ * @see
1034
+ * XXH3_128bits_reset(), XXH3_128bits_update(), XXH3_128bits_digest(): Streaming version.
1035
+ */
1036
+ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(const void* data, size_t len);
1037
+ /*! @brief Seeded 128-bit variant of XXH3. @see XXH3_64bits_withSeed(). */
1038
+ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
1039
+ /*! @brief Custom secret 128-bit variant of XXH3. @see XXH3_64bits_withSecret(). */
1040
+ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
891
1041
 
892
1042
  /******* Streaming *******/
1043
+ #ifndef XXH_NO_STREAM
893
1044
  /*
894
1045
  * Streaming requires state maintenance.
895
1046
  * This operation costs memory and CPU.
@@ -907,7 +1058,8 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr,
907
1058
  XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
908
1059
 
909
1060
  XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
910
- XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);
1061
+ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);
1062
+ #endif /* !XXH_NO_STREAM */
911
1063
 
912
1064
  /* Following helper functions make it possible to compare XXH128_hast_t values.
913
1065
  * Since XXH128_hash_t is a structure, this capability is not offered by the language.
@@ -917,24 +1069,23 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);
917
1069
  * XXH128_isEqual():
918
1070
  * Return: 1 if `h1` and `h2` are equal, 0 if they are not.
919
1071
  */
920
- XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2);
1072
+ XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2);
921
1073
 
922
1074
  /*!
923
- * XXH128_cmp():
924
- *
1075
+ * @brief Compares two @ref XXH128_hash_t
925
1076
  * This comparator is compatible with stdlib's `qsort()`/`bsearch()`.
926
1077
  *
927
- * return: >0 if *h128_1 > *h128_2
928
- * =0 if *h128_1 == *h128_2
929
- * <0 if *h128_1 < *h128_2
1078
+ * @return: >0 if *h128_1 > *h128_2
1079
+ * =0 if *h128_1 == *h128_2
1080
+ * <0 if *h128_1 < *h128_2
930
1081
  */
931
- XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2);
1082
+ XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(const void* h128_1, const void* h128_2);
932
1083
 
933
1084
 
934
1085
  /******* Canonical representation *******/
935
1086
  typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t;
936
1087
  XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash);
937
- XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src);
1088
+ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src);
938
1089
 
939
1090
 
940
1091
  #endif /* !XXH_NO_XXH3 */
@@ -1075,7 +1226,7 @@ struct XXH64_state_s {
1075
1226
  */
1076
1227
  struct XXH3_state_s {
1077
1228
  XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]);
1078
- /*!< The 8 accumulators. Similar to `vN` in @ref XXH32_state_s::v1 and @ref XXH64_state_s */
1229
+ /*!< The 8 accumulators. See @ref XXH32_state_s::v and @ref XXH64_state_s::v */
1079
1230
  XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]);
1080
1231
  /*!< Used to store a custom secret generated from a seed. */
1081
1232
  XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]);
@@ -1118,66 +1269,111 @@ struct XXH3_state_s {
1118
1269
  #define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; }
1119
1270
 
1120
1271
 
1121
- /* XXH128() :
1272
+ /*!
1122
1273
  * simple alias to pre-selected XXH3_128bits variant
1123
1274
  */
1124
- XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
1275
+ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
1125
1276
 
1126
1277
 
1127
1278
  /* === Experimental API === */
1128
1279
  /* Symbols defined below must be considered tied to a specific library version. */
1129
1280
 
1130
- /*
1281
+ /*!
1131
1282
  * XXH3_generateSecret():
1132
1283
  *
1133
1284
  * Derive a high-entropy secret from any user-defined content, named customSeed.
1134
1285
  * The generated secret can be used in combination with `*_withSecret()` functions.
1135
- * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed,
1136
- * as it becomes much more difficult for an external actor to guess how to impact the calculation logic.
1286
+ * The `_withSecret()` variants are useful to provide a higher level of protection
1287
+ * than 64-bit seed, as it becomes much more difficult for an external actor to
1288
+ * guess how to impact the calculation logic.
1137
1289
  *
1138
1290
  * The function accepts as input a custom seed of any length and any content,
1139
- * and derives from it a high-entropy secret of length @secretSize
1140
- * into an already allocated buffer @secretBuffer.
1141
- * @secretSize must be >= XXH3_SECRET_SIZE_MIN
1291
+ * and derives from it a high-entropy secret of length @p secretSize into an
1292
+ * already allocated buffer @p secretBuffer.
1142
1293
  *
1143
1294
  * The generated secret can then be used with any `*_withSecret()` variant.
1144
- * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`,
1145
- * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()`
1295
+ * The functions @ref XXH3_128bits_withSecret(), @ref XXH3_64bits_withSecret(),
1296
+ * @ref XXH3_128bits_reset_withSecret() and @ref XXH3_64bits_reset_withSecret()
1146
1297
  * are part of this list. They all accept a `secret` parameter
1147
- * which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN)
1298
+ * which must be large enough for implementation reasons (>= @ref XXH3_SECRET_SIZE_MIN)
1148
1299
  * _and_ feature very high entropy (consist of random-looking bytes).
1149
- * These conditions can be a high bar to meet, so
1150
- * XXH3_generateSecret() can be employed to ensure proper quality.
1300
+ * These conditions can be a high bar to meet, so @ref XXH3_generateSecret() can
1301
+ * be employed to ensure proper quality.
1151
1302
  *
1152
- * customSeed can be anything. It can have any size, even small ones,
1153
- * and its content can be anything, even "poor entropy" sources such as a bunch of zeroes.
1154
- * The resulting `secret` will nonetheless provide all required qualities.
1303
+ * @p customSeed can be anything. It can have any size, even small ones,
1304
+ * and its content can be anything, even "poor entropy" sources such as a bunch
1305
+ * of zeroes. The resulting `secret` will nonetheless provide all required qualities.
1155
1306
  *
1156
- * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior.
1307
+ * @pre
1308
+ * - @p secretSize must be >= @ref XXH3_SECRET_SIZE_MIN
1309
+ * - When @p customSeedSize > 0, supplying NULL as customSeed is undefined behavior.
1310
+ *
1311
+ * Example code:
1312
+ * @code{.c}
1313
+ * #include <stdio.h>
1314
+ * #include <stdlib.h>
1315
+ * #include <string.h>
1316
+ * #define XXH_STATIC_LINKING_ONLY // expose unstable API
1317
+ * #include "xxhash.h"
1318
+ * // Hashes argv[2] using the entropy from argv[1].
1319
+ * int main(int argc, char* argv[])
1320
+ * {
1321
+ * char secret[XXH3_SECRET_SIZE_MIN];
1322
+ * if (argv != 3) { return 1; }
1323
+ * XXH3_generateSecret(secret, sizeof(secret), argv[1], strlen(argv[1]));
1324
+ * XXH64_hash_t h = XXH3_64bits_withSecret(
1325
+ * argv[2], strlen(argv[2]),
1326
+ * secret, sizeof(secret)
1327
+ * );
1328
+ * printf("%016llx\n", (unsigned long long) h);
1329
+ * }
1330
+ * @endcode
1157
1331
  */
1158
1332
  XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize);
1159
1333
 
1160
-
1161
- /*
1162
- * XXH3_generateSecret_fromSeed():
1163
- *
1164
- * Generate the same secret as the _withSeed() variants.
1165
- *
1166
- * The resulting secret has a length of XXH3_SECRET_DEFAULT_SIZE (necessarily).
1167
- * @secretBuffer must be already allocated, of size at least XXH3_SECRET_DEFAULT_SIZE bytes.
1334
+ /*!
1335
+ * @brief Generate the same secret as the _withSeed() variants.
1168
1336
  *
1169
1337
  * The generated secret can be used in combination with
1170
1338
  *`*_withSecret()` and `_withSecretandSeed()` variants.
1171
- * This generator is notably useful in combination with `_withSecretandSeed()`,
1172
- * as a way to emulate a faster `_withSeed()` variant.
1339
+ *
1340
+ * Example C++ `std::string` hash class:
1341
+ * @code{.cpp}
1342
+ * #include <string>
1343
+ * #define XXH_STATIC_LINKING_ONLY // expose unstable API
1344
+ * #include "xxhash.h"
1345
+ * // Slow, seeds each time
1346
+ * class HashSlow {
1347
+ * XXH64_hash_t seed;
1348
+ * public:
1349
+ * HashSlow(XXH64_hash_t s) : seed{s} {}
1350
+ * size_t operator()(const std::string& x) const {
1351
+ * return size_t{XXH3_64bits_withSeed(x.c_str(), x.length(), seed)};
1352
+ * }
1353
+ * };
1354
+ * // Fast, caches the seeded secret for future uses.
1355
+ * class HashFast {
1356
+ * unsigned char secret[XXH3_SECRET_SIZE_MIN];
1357
+ * public:
1358
+ * HashFast(XXH64_hash_t s) {
1359
+ * XXH3_generateSecret_fromSeed(secret, seed);
1360
+ * }
1361
+ * size_t operator()(const std::string& x) const {
1362
+ * return size_t{
1363
+ * XXH3_64bits_withSecret(x.c_str(), x.length(), secret, sizeof(secret))
1364
+ * };
1365
+ * }
1366
+ * };
1367
+ * @endcode
1368
+ * @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes
1369
+ * @param seed The seed to seed the state.
1173
1370
  */
1174
1371
  XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed);
1175
1372
 
1176
- /*
1177
- * *_withSecretandSeed() :
1373
+ /*!
1178
1374
  * These variants generate hash values using either
1179
- * @seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes)
1180
- * or @secret for "large" keys (>= XXH3_MIDSIZE_MAX).
1375
+ * @p seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes)
1376
+ * or @p secret for "large" keys (>= XXH3_MIDSIZE_MAX).
1181
1377
  *
1182
1378
  * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`.
1183
1379
  * `_withSeed()` has to generate the secret on the fly for "large" keys.
@@ -1186,7 +1382,7 @@ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_
1186
1382
  * which requires more instructions than _withSeed() variants.
1187
1383
  * Therefore, _withSecretandSeed variant combines the best of both worlds.
1188
1384
  *
1189
- * When @secret has been generated by XXH3_generateSecret_fromSeed(),
1385
+ * When @p secret has been generated by XXH3_generateSecret_fromSeed(),
1190
1386
  * this variant produces *exactly* the same results as `_withSeed()` variant,
1191
1387
  * hence offering only a pure speed benefit on "large" input,
1192
1388
  * by skipping the need to regenerate the secret for every large input.
@@ -1195,31 +1391,32 @@ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_
1195
1391
  * for example with XXH3_64bits(), which then becomes the seed,
1196
1392
  * and then employ both the seed and the secret in _withSecretandSeed().
1197
1393
  * On top of speed, an added benefit is that each bit in the secret
1198
- * has a 50% chance to swap each bit in the output,
1199
- * via its impact to the seed.
1394
+ * has a 50% chance to swap each bit in the output, via its impact to the seed.
1395
+ *
1200
1396
  * This is not guaranteed when using the secret directly in "small data" scenarios,
1201
1397
  * because only portions of the secret are employed for small data.
1202
1398
  */
1203
- XXH_PUBLIC_API XXH64_hash_t
1399
+ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t
1204
1400
  XXH3_64bits_withSecretandSeed(const void* data, size_t len,
1205
1401
  const void* secret, size_t secretSize,
1206
1402
  XXH64_hash_t seed);
1207
-
1208
- XXH_PUBLIC_API XXH128_hash_t
1209
- XXH3_128bits_withSecretandSeed(const void* data, size_t len,
1403
+ /*! @copydoc XXH3_64bits_withSecretandSeed() */
1404
+ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t
1405
+ XXH3_128bits_withSecretandSeed(const void* input, size_t length,
1210
1406
  const void* secret, size_t secretSize,
1211
1407
  XXH64_hash_t seed64);
1212
-
1408
+ #ifndef XXH_NO_STREAM
1409
+ /*! @copydoc XXH3_64bits_withSecretandSeed() */
1213
1410
  XXH_PUBLIC_API XXH_errorcode
1214
1411
  XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1215
1412
  const void* secret, size_t secretSize,
1216
1413
  XXH64_hash_t seed64);
1217
-
1414
+ /*! @copydoc XXH3_64bits_withSecretandSeed() */
1218
1415
  XXH_PUBLIC_API XXH_errorcode
1219
1416
  XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1220
1417
  const void* secret, size_t secretSize,
1221
1418
  XXH64_hash_t seed64);
1222
-
1419
+ #endif /* !XXH_NO_STREAM */
1223
1420
 
1224
1421
  #endif /* !XXH_NO_XXH3 */
1225
1422
  #endif /* XXH_NO_LONG_LONG */
@@ -1275,7 +1472,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1275
1472
  /*!
1276
1473
  * @brief Define this to disable 64-bit code.
1277
1474
  *
1278
- * Useful if only using the @ref xxh32_family and you have a strict C90 compiler.
1475
+ * Useful if only using the @ref XXH32_family and you have a strict C90 compiler.
1279
1476
  */
1280
1477
  # define XXH_NO_LONG_LONG
1281
1478
  # undef XXH_NO_LONG_LONG /* don't actually */
@@ -1331,6 +1528,34 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1331
1528
  */
1332
1529
  # define XXH_FORCE_MEMORY_ACCESS 0
1333
1530
 
1531
+ /*!
1532
+ * @def XXH_SIZE_OPT
1533
+ * @brief Controls how much xxHash optimizes for size.
1534
+ *
1535
+ * xxHash, when compiled, tends to result in a rather large binary size. This
1536
+ * is mostly due to heavy usage to forced inlining and constant folding of the
1537
+ * @ref XXH3_family to increase performance.
1538
+ *
1539
+ * However, some developers prefer size over speed. This option can
1540
+ * significantly reduce the size of the generated code. When using the `-Os`
1541
+ * or `-Oz` options on GCC or Clang, this is defined to 1 by default,
1542
+ * otherwise it is defined to 0.
1543
+ *
1544
+ * Most of these size optimizations can be controlled manually.
1545
+ *
1546
+ * This is a number from 0-2.
1547
+ * - `XXH_SIZE_OPT` == 0: Default. xxHash makes no size optimizations. Speed
1548
+ * comes first.
1549
+ * - `XXH_SIZE_OPT` == 1: Default for `-Os` and `-Oz`. xxHash is more
1550
+ * conservative and disables hacks that increase code size. It implies the
1551
+ * options @ref XXH_NO_INLINE_HINTS == 1, @ref XXH_FORCE_ALIGN_CHECK == 0,
1552
+ * and @ref XXH3_NEON_LANES == 8 if they are not already defined.
1553
+ * - `XXH_SIZE_OPT` == 2: xxHash tries to make itself as small as possible.
1554
+ * Performance may cry. For example, the single shot functions just use the
1555
+ * streaming API.
1556
+ */
1557
+ # define XXH_SIZE_OPT 0
1558
+
1334
1559
  /*!
1335
1560
  * @def XXH_FORCE_ALIGN_CHECK
1336
1561
  * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32()
@@ -1352,9 +1577,11 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1352
1577
  *
1353
1578
  * In these cases, the alignment check can be removed by setting this macro to 0.
1354
1579
  * Then the code will always use unaligned memory access.
1355
- * Align check is automatically disabled on x86, x64 & arm64,
1580
+ * Align check is automatically disabled on x86, x64, ARM64, and some ARM chips
1356
1581
  * which are platforms known to offer good unaligned memory accesses performance.
1357
1582
  *
1583
+ * It is also disabled by default when @ref XXH_SIZE_OPT >= 1.
1584
+ *
1358
1585
  * This option does not affect XXH3 (only XXH32 and XXH64).
1359
1586
  */
1360
1587
  # define XXH_FORCE_ALIGN_CHECK 0
@@ -1376,8 +1603,8 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1376
1603
  * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the
1377
1604
  * compiler full control on whether to inline or not.
1378
1605
  *
1379
- * When not optimizing (-O0), optimizing for size (-Os, -Oz), or using
1380
- * -fno-inline with GCC or Clang, this will automatically be defined.
1606
+ * When not optimizing (-O0), using `-fno-inline` with GCC or Clang, or if
1607
+ * @ref XXH_SIZE_OPT >= 1, this will automatically be defined.
1381
1608
  */
1382
1609
  # define XXH_NO_INLINE_HINTS 0
1383
1610
 
@@ -1402,6 +1629,17 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1402
1629
  */
1403
1630
  # define XXH_OLD_NAMES
1404
1631
  # undef XXH_OLD_NAMES /* don't actually use, it is ugly. */
1632
+
1633
+ /*!
1634
+ * @def XXH_NO_STREAM
1635
+ * @brief Disables the streaming API.
1636
+ *
1637
+ * When xxHash is not inlined and the streaming functions are not used, disabling
1638
+ * the streaming functions can improve code size significantly, especially with
1639
+ * the @ref XXH3_family which tends to make constant folded copies of itself.
1640
+ */
1641
+ # define XXH_NO_STREAM
1642
+ # undef XXH_NO_STREAM /* don't actually */
1405
1643
  #endif /* XXH_DOXYGEN */
1406
1644
  /*!
1407
1645
  * @}
@@ -1416,9 +1654,19 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1416
1654
  # endif
1417
1655
  #endif
1418
1656
 
1657
+ #ifndef XXH_SIZE_OPT
1658
+ /* default to 1 for -Os or -Oz */
1659
+ # if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE_SIZE__)
1660
+ # define XXH_SIZE_OPT 1
1661
+ # else
1662
+ # define XXH_SIZE_OPT 0
1663
+ # endif
1664
+ #endif
1665
+
1419
1666
  #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
1420
- /* don't check on x86, aarch64, or arm when unaligned access is available */
1421
- # if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) || defined(__ARM_FEATURE_UNALIGNED) \
1667
+ /* don't check on sizeopt, x86, aarch64, or arm when unaligned access is available */
1668
+ # if XXH_SIZE_OPT >= 1 || \
1669
+ defined(__i386) || defined(__x86_64__) || defined(__aarch64__) || defined(__ARM_FEATURE_UNALIGNED) \
1422
1670
  || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) || defined(_M_ARM) /* visual */
1423
1671
  # define XXH_FORCE_ALIGN_CHECK 0
1424
1672
  # else
@@ -1427,8 +1675,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1427
1675
  #endif
1428
1676
 
1429
1677
  #ifndef XXH_NO_INLINE_HINTS
1430
- # if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \
1431
- || defined(__NO_INLINE__) /* -O0, -fno-inline */
1678
+ # if XXH_SIZE_OPT >= 1 || defined(__NO_INLINE__) /* -O0, -fno-inline */
1432
1679
  # define XXH_NO_INLINE_HINTS 1
1433
1680
  # else
1434
1681
  # define XXH_NO_INLINE_HINTS 0
@@ -1449,6 +1696,24 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1449
1696
  /* *************************************
1450
1697
  * Includes & Memory related functions
1451
1698
  ***************************************/
1699
+ #if defined(XXH_NO_STREAM)
1700
+ /* nothing */
1701
+ #elif defined(XXH_NO_STDLIB)
1702
+
1703
+ /* When requesting to disable any mention of stdlib,
1704
+ * the library loses the ability to invoked malloc / free.
1705
+ * In practice, it means that functions like `XXH*_createState()`
1706
+ * will always fail, and return NULL.
1707
+ * This flag is useful in situations where
1708
+ * xxhash.h is integrated into some kernel, embedded or limited environment
1709
+ * without access to dynamic allocation.
1710
+ */
1711
+
1712
+ static XXH_CONSTF void* XXH_malloc(size_t s) { (void)s; return NULL; }
1713
+ static void XXH_free(void* p) { (void)p; }
1714
+
1715
+ #else
1716
+
1452
1717
  /*
1453
1718
  * Modify the local functions below should you wish to use
1454
1719
  * different memory routines for malloc() and free()
@@ -1459,13 +1724,15 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1459
1724
  * @internal
1460
1725
  * @brief Modify this function to use a different routine than malloc().
1461
1726
  */
1462
- static void* XXH_malloc(size_t s) { return ruby_xmalloc(s); }
1727
+ static XXH_MALLOCF void* XXH_malloc(size_t s) { return malloc(s); }
1463
1728
 
1464
1729
  /*!
1465
1730
  * @internal
1466
1731
  * @brief Modify this function to use a different routine than free().
1467
1732
  */
1468
- static void XXH_free(void* p) { ruby_xfree(p); }
1733
+ static void XXH_free(void* p) { free(p); }
1734
+
1735
+ #endif /* XXH_NO_STDLIB */
1469
1736
 
1470
1737
  #include <string.h>
1471
1738
 
@@ -1542,8 +1809,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
1542
1809
  /* note: use after variable declarations */
1543
1810
  #ifndef XXH_STATIC_ASSERT
1544
1811
  # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */
1545
- # include <assert.h>
1546
- # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
1812
+ # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { _Static_assert((c),m); } while(0)
1547
1813
  # elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */
1548
1814
  # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
1549
1815
  # else
@@ -1878,8 +2144,10 @@ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
1878
2144
  *********************************************************************/
1879
2145
  /*!
1880
2146
  * @}
1881
- * @defgroup xxh32_impl XXH32 implementation
2147
+ * @defgroup XXH32_impl XXH32 implementation
1882
2148
  * @ingroup impl
2149
+ *
2150
+ * Details on the XXH32 implementation.
1883
2151
  * @{
1884
2152
  */
1885
2153
  /* #define instead of static const, to be used as initializers */
@@ -1959,17 +2227,17 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
1959
2227
  * The final mix ensures that all input bits have a chance to impact any bit in
1960
2228
  * the output digest, resulting in an unbiased distribution.
1961
2229
  *
1962
- * @param h32 The hash to avalanche.
2230
+ * @param hash The hash to avalanche.
1963
2231
  * @return The avalanched hash.
1964
2232
  */
1965
- static xxh_u32 XXH32_avalanche(xxh_u32 h32)
2233
+ static xxh_u32 XXH32_avalanche(xxh_u32 hash)
1966
2234
  {
1967
- h32 ^= h32 >> 15;
1968
- h32 *= XXH_PRIME32_2;
1969
- h32 ^= h32 >> 13;
1970
- h32 *= XXH_PRIME32_3;
1971
- h32 ^= h32 >> 16;
1972
- return(h32);
2235
+ hash ^= hash >> 15;
2236
+ hash *= XXH_PRIME32_2;
2237
+ hash ^= hash >> 13;
2238
+ hash *= XXH_PRIME32_3;
2239
+ hash ^= hash >> 16;
2240
+ return hash;
1973
2241
  }
1974
2242
 
1975
2243
  #define XXH_get32bits(p) XXH_readLE32_align(p, align)
@@ -1982,24 +2250,25 @@ static xxh_u32 XXH32_avalanche(xxh_u32 h32)
1982
2250
  * This final stage will digest them to ensure that all input bytes are present
1983
2251
  * in the final mix.
1984
2252
  *
1985
- * @param h32 The hash to finalize.
2253
+ * @param hash The hash to finalize.
1986
2254
  * @param ptr The pointer to the remaining input.
1987
2255
  * @param len The remaining length, modulo 16.
1988
2256
  * @param align Whether @p ptr is aligned.
1989
2257
  * @return The finalized hash.
2258
+ * @see XXH64_finalize().
1990
2259
  */
1991
- static xxh_u32
1992
- XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
2260
+ static XXH_PUREF xxh_u32
2261
+ XXH32_finalize(xxh_u32 hash, const xxh_u8* ptr, size_t len, XXH_alignment align)
1993
2262
  {
1994
- #define XXH_PROCESS1 do { \
1995
- h32 += (*ptr++) * XXH_PRIME32_5; \
1996
- h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \
2263
+ #define XXH_PROCESS1 do { \
2264
+ hash += (*ptr++) * XXH_PRIME32_5; \
2265
+ hash = XXH_rotl32(hash, 11) * XXH_PRIME32_1; \
1997
2266
  } while (0)
1998
2267
 
1999
- #define XXH_PROCESS4 do { \
2000
- h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \
2001
- ptr += 4; \
2002
- h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \
2268
+ #define XXH_PROCESS4 do { \
2269
+ hash += XXH_get32bits(ptr) * XXH_PRIME32_3; \
2270
+ ptr += 4; \
2271
+ hash = XXH_rotl32(hash, 17) * XXH_PRIME32_4; \
2003
2272
  } while (0)
2004
2273
 
2005
2274
  if (ptr==NULL) XXH_ASSERT(len == 0);
@@ -2015,7 +2284,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
2015
2284
  XXH_PROCESS1;
2016
2285
  --len;
2017
2286
  }
2018
- return XXH32_avalanche(h32);
2287
+ return XXH32_avalanche(hash);
2019
2288
  } else {
2020
2289
  switch(len&15) /* or switch(bEnd - p) */ {
2021
2290
  case 12: XXH_PROCESS4;
@@ -2023,7 +2292,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
2023
2292
  case 8: XXH_PROCESS4;
2024
2293
  XXH_FALLTHROUGH;
2025
2294
  case 4: XXH_PROCESS4;
2026
- return XXH32_avalanche(h32);
2295
+ return XXH32_avalanche(hash);
2027
2296
 
2028
2297
  case 13: XXH_PROCESS4;
2029
2298
  XXH_FALLTHROUGH;
@@ -2031,7 +2300,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
2031
2300
  XXH_FALLTHROUGH;
2032
2301
  case 5: XXH_PROCESS4;
2033
2302
  XXH_PROCESS1;
2034
- return XXH32_avalanche(h32);
2303
+ return XXH32_avalanche(hash);
2035
2304
 
2036
2305
  case 14: XXH_PROCESS4;
2037
2306
  XXH_FALLTHROUGH;
@@ -2040,7 +2309,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
2040
2309
  case 6: XXH_PROCESS4;
2041
2310
  XXH_PROCESS1;
2042
2311
  XXH_PROCESS1;
2043
- return XXH32_avalanche(h32);
2312
+ return XXH32_avalanche(hash);
2044
2313
 
2045
2314
  case 15: XXH_PROCESS4;
2046
2315
  XXH_FALLTHROUGH;
@@ -2054,10 +2323,10 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
2054
2323
  XXH_FALLTHROUGH;
2055
2324
  case 1: XXH_PROCESS1;
2056
2325
  XXH_FALLTHROUGH;
2057
- case 0: return XXH32_avalanche(h32);
2326
+ case 0: return XXH32_avalanche(hash);
2058
2327
  }
2059
2328
  XXH_ASSERT(0);
2060
- return h32; /* reaching this point is deemed impossible */
2329
+ return hash; /* reaching this point is deemed impossible */
2061
2330
  }
2062
2331
  }
2063
2332
 
@@ -2077,7 +2346,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
2077
2346
  * @param align Whether @p input is aligned.
2078
2347
  * @return The calculated hash.
2079
2348
  */
2080
- XXH_FORCE_INLINE xxh_u32
2349
+ XXH_FORCE_INLINE XXH_PUREF xxh_u32
2081
2350
  XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align)
2082
2351
  {
2083
2352
  xxh_u32 h32;
@@ -2110,10 +2379,10 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment
2110
2379
  return XXH32_finalize(h32, input, len&15, align);
2111
2380
  }
2112
2381
 
2113
- /*! @ingroup xxh32_family */
2382
+ /*! @ingroup XXH32_family */
2114
2383
  XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed)
2115
2384
  {
2116
- #if 0
2385
+ #if !defined(XXH_NO_STREAM) && XXH_SIZE_OPT >= 2
2117
2386
  /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
2118
2387
  XXH32_state_t state;
2119
2388
  XXH32_reset(&state, seed);
@@ -2132,27 +2401,26 @@ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t s
2132
2401
 
2133
2402
 
2134
2403
  /******* Hash streaming *******/
2135
- /*!
2136
- * @ingroup xxh32_family
2137
- */
2404
+ #ifndef XXH_NO_STREAM
2405
+ /*! @ingroup XXH32_family */
2138
2406
  XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
2139
2407
  {
2140
2408
  return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
2141
2409
  }
2142
- /*! @ingroup xxh32_family */
2410
+ /*! @ingroup XXH32_family */
2143
2411
  XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
2144
2412
  {
2145
2413
  XXH_free(statePtr);
2146
2414
  return XXH_OK;
2147
2415
  }
2148
2416
 
2149
- /*! @ingroup xxh32_family */
2417
+ /*! @ingroup XXH32_family */
2150
2418
  XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
2151
2419
  {
2152
2420
  XXH_memcpy(dstState, srcState, sizeof(*dstState));
2153
2421
  }
2154
2422
 
2155
- /*! @ingroup xxh32_family */
2423
+ /*! @ingroup XXH32_family */
2156
2424
  XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed)
2157
2425
  {
2158
2426
  XXH_ASSERT(statePtr != NULL);
@@ -2165,7 +2433,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s
2165
2433
  }
2166
2434
 
2167
2435
 
2168
- /*! @ingroup xxh32_family */
2436
+ /*! @ingroup XXH32_family */
2169
2437
  XXH_PUBLIC_API XXH_errorcode
2170
2438
  XXH32_update(XXH32_state_t* state, const void* input, size_t len)
2171
2439
  {
@@ -2220,7 +2488,7 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len)
2220
2488
  }
2221
2489
 
2222
2490
 
2223
- /*! @ingroup xxh32_family */
2491
+ /*! @ingroup XXH32_family */
2224
2492
  XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
2225
2493
  {
2226
2494
  xxh_u32 h32;
@@ -2238,12 +2506,12 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
2238
2506
 
2239
2507
  return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned);
2240
2508
  }
2241
-
2509
+ #endif /* !XXH_NO_STREAM */
2242
2510
 
2243
2511
  /******* Canonical representation *******/
2244
2512
 
2245
2513
  /*!
2246
- * @ingroup xxh32_family
2514
+ * @ingroup XXH32_family
2247
2515
  * The default return values from XXH functions are unsigned 32 and 64 bit
2248
2516
  * integers.
2249
2517
  *
@@ -2262,7 +2530,7 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t
2262
2530
  if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
2263
2531
  XXH_memcpy(dst, &hash, sizeof(*dst));
2264
2532
  }
2265
- /*! @ingroup xxh32_family */
2533
+ /*! @ingroup XXH32_family */
2266
2534
  XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
2267
2535
  {
2268
2536
  return XXH_readBE32(src);
@@ -2406,8 +2674,10 @@ XXH_readLE64_align(const void* ptr, XXH_alignment align)
2406
2674
  /******* xxh64 *******/
2407
2675
  /*!
2408
2676
  * @}
2409
- * @defgroup xxh64_impl XXH64 implementation
2677
+ * @defgroup XXH64_impl XXH64 implementation
2410
2678
  * @ingroup impl
2679
+ *
2680
+ * Details on the XXH64 implementation.
2411
2681
  * @{
2412
2682
  */
2413
2683
  /* #define rather that static const, to be used as initializers */
@@ -2425,6 +2695,7 @@ XXH_readLE64_align(const void* ptr, XXH_alignment align)
2425
2695
  # define PRIME64_5 XXH_PRIME64_5
2426
2696
  #endif
2427
2697
 
2698
+ /*! @copydoc XXH32_round */
2428
2699
  static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input)
2429
2700
  {
2430
2701
  acc += input * XXH_PRIME64_2;
@@ -2441,43 +2712,59 @@ static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val)
2441
2712
  return acc;
2442
2713
  }
2443
2714
 
2444
- static xxh_u64 XXH64_avalanche(xxh_u64 h64)
2715
+ /*! @copydoc XXH32_avalanche */
2716
+ static xxh_u64 XXH64_avalanche(xxh_u64 hash)
2445
2717
  {
2446
- h64 ^= h64 >> 33;
2447
- h64 *= XXH_PRIME64_2;
2448
- h64 ^= h64 >> 29;
2449
- h64 *= XXH_PRIME64_3;
2450
- h64 ^= h64 >> 32;
2451
- return h64;
2718
+ hash ^= hash >> 33;
2719
+ hash *= XXH_PRIME64_2;
2720
+ hash ^= hash >> 29;
2721
+ hash *= XXH_PRIME64_3;
2722
+ hash ^= hash >> 32;
2723
+ return hash;
2452
2724
  }
2453
2725
 
2454
2726
 
2455
2727
  #define XXH_get64bits(p) XXH_readLE64_align(p, align)
2456
2728
 
2457
- static xxh_u64
2458
- XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align)
2729
+ /*!
2730
+ * @internal
2731
+ * @brief Processes the last 0-31 bytes of @p ptr.
2732
+ *
2733
+ * There may be up to 31 bytes remaining to consume from the input.
2734
+ * This final stage will digest them to ensure that all input bytes are present
2735
+ * in the final mix.
2736
+ *
2737
+ * @param hash The hash to finalize.
2738
+ * @param ptr The pointer to the remaining input.
2739
+ * @param len The remaining length, modulo 32.
2740
+ * @param align Whether @p ptr is aligned.
2741
+ * @return The finalized hash
2742
+ * @see XXH32_finalize().
2743
+ */
2744
+ static XXH_PUREF xxh_u64
2745
+ XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align)
2459
2746
  {
2460
2747
  if (ptr==NULL) XXH_ASSERT(len == 0);
2461
2748
  len &= 31;
2462
2749
  while (len >= 8) {
2463
2750
  xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr));
2464
2751
  ptr += 8;
2465
- h64 ^= k1;
2466
- h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4;
2752
+ hash ^= k1;
2753
+ hash = XXH_rotl64(hash,27) * XXH_PRIME64_1 + XXH_PRIME64_4;
2467
2754
  len -= 8;
2468
2755
  }
2469
2756
  if (len >= 4) {
2470
- h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1;
2757
+ hash ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1;
2471
2758
  ptr += 4;
2472
- h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
2759
+ hash = XXH_rotl64(hash, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
2473
2760
  len -= 4;
2474
2761
  }
2475
2762
  while (len > 0) {
2476
- h64 ^= (*ptr++) * XXH_PRIME64_5;
2477
- h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1;
2763
+ hash ^= (*ptr++) * XXH_PRIME64_5;
2764
+ hash = XXH_rotl64(hash, 11) * XXH_PRIME64_1;
2478
2765
  --len;
2479
2766
  }
2480
- return XXH64_avalanche(h64);
2767
+ return XXH64_avalanche(hash);
2481
2768
  }
2482
2769
 
2483
2770
  #ifdef XXH_OLD_NAMES
@@ -2490,7 +2777,15 @@ XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align)
2490
2777
  # undef XXH_PROCESS8_64
2491
2778
  #endif
2492
2779
 
2493
- XXH_FORCE_INLINE xxh_u64
2780
+ /*!
2781
+ * @internal
2782
+ * @brief The implementation for @ref XXH64().
2783
+ *
2784
+ * @param input , len , seed Directly passed from @ref XXH64().
2785
+ * @param align Whether @p input is aligned.
2786
+ * @return The calculated hash.
2787
+ */
2788
+ XXH_FORCE_INLINE XXH_PUREF xxh_u64
2494
2789
  XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align)
2495
2790
  {
2496
2791
  xxh_u64 h64;
@@ -2527,10 +2822,10 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment
2527
2822
  }
2528
2823
 
2529
2824
 
2530
- /*! @ingroup xxh64_family */
2825
+ /*! @ingroup XXH64_family */
2531
2826
  XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed)
2532
2827
  {
2533
- #if 0
2828
+ #if !defined(XXH_NO_STREAM) && XXH_SIZE_OPT >= 2
2534
2829
  /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
2535
2830
  XXH64_state_t state;
2536
2831
  XXH64_reset(&state, seed);
@@ -2548,26 +2843,26 @@ XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t s
2548
2843
  }
2549
2844
 
2550
2845
  /******* Hash Streaming *******/
2551
-
2552
- /*! @ingroup xxh64_family*/
2846
+ #ifndef XXH_NO_STREAM
2847
+ /*! @ingroup XXH64_family*/
2553
2848
  XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
2554
2849
  {
2555
2850
  return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
2556
2851
  }
2557
- /*! @ingroup xxh64_family */
2852
+ /*! @ingroup XXH64_family */
2558
2853
  XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
2559
2854
  {
2560
2855
  XXH_free(statePtr);
2561
2856
  return XXH_OK;
2562
2857
  }
2563
2858
 
2564
- /*! @ingroup xxh64_family */
2859
+ /*! @ingroup XXH64_family */
2565
2860
  XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
2566
2861
  {
2567
2862
  XXH_memcpy(dstState, srcState, sizeof(*dstState));
2568
2863
  }
2569
2864
 
2570
- /*! @ingroup xxh64_family */
2865
+ /*! @ingroup XXH64_family */
2571
2866
  XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed)
2572
2867
  {
2573
2868
  XXH_ASSERT(statePtr != NULL);
@@ -2579,7 +2874,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t s
2579
2874
  return XXH_OK;
2580
2875
  }
2581
2876
 
2582
- /*! @ingroup xxh64_family */
2877
+ /*! @ingroup XXH64_family */
2583
2878
  XXH_PUBLIC_API XXH_errorcode
2584
2879
  XXH64_update (XXH64_state_t* state, const void* input, size_t len)
2585
2880
  {
@@ -2631,7 +2926,7 @@ XXH64_update (XXH64_state_t* state, const void* input, size_t len)
2631
2926
  }
2632
2927
 
2633
2928
 
2634
- /*! @ingroup xxh64_family */
2929
+ /*! @ingroup XXH64_family */
2635
2930
  XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state)
2636
2931
  {
2637
2932
  xxh_u64 h64;
@@ -2650,11 +2945,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state)
2650
2945
 
2651
2946
  return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned);
2652
2947
  }
2653
-
2948
+ #endif /* !XXH_NO_STREAM */
2654
2949
 
2655
2950
  /******* Canonical representation *******/
2656
2951
 
2657
- /*! @ingroup xxh64_family */
2952
+ /*! @ingroup XXH64_family */
2658
2953
  XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
2659
2954
  {
2660
2955
  XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
@@ -2662,7 +2957,7 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t
2662
2957
  XXH_memcpy(dst, &hash, sizeof(*dst));
2663
2958
  }
2664
2959
 
2665
- /*! @ingroup xxh64_family */
2960
+ /*! @ingroup XXH64_family */
2666
2961
  XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
2667
2962
  {
2668
2963
  return XXH_readBE64(src);
@@ -2676,7 +2971,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src
2676
2971
  ************************************************************************ */
2677
2972
  /*!
2678
2973
  * @}
2679
- * @defgroup xxh3_impl XXH3 implementation
2974
+ * @defgroup XXH3_impl XXH3 implementation
2680
2975
  * @ingroup impl
2681
2976
  * @{
2682
2977
  */
@@ -2929,7 +3224,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
2929
3224
  */
2930
3225
  #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
2931
3226
  && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
2932
- && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
3227
+ && defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0 /* respect -O0 and -Os */
2933
3228
  # pragma GCC push_options
2934
3229
  # pragma GCC optimize("-O2")
2935
3230
  #endif
@@ -3099,7 +3394,7 @@ XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr)
3099
3394
  */
3100
3395
  # ifndef XXH3_NEON_LANES
3101
3396
  # if (defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) \
3102
- && !defined(__OPTIMIZE_SIZE__)
3397
+ && XXH_SIZE_OPT <= 0
3103
3398
  # define XXH3_NEON_LANES 6
3104
3399
  # else
3105
3400
  # define XXH3_NEON_LANES XXH_ACC_NB
@@ -3116,23 +3411,33 @@ XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr)
3116
3411
  * inconsistent intrinsics, spotty coverage, and multiple endiannesses.
3117
3412
  */
3118
3413
  #if XXH_VECTOR == XXH_VSX
3414
+ /* Annoyingly, these headers _may_ define three macros: `bool`, `vector`,
3415
+ * and `pixel`. This is a problem for obvious reasons.
3416
+ *
3417
+ * These keywords are unnecessary; the spec literally says they are
3418
+ * equivalent to `__bool`, `__vector`, and `__pixel` and may be undef'd
3419
+ * after including the header.
3420
+ *
3421
+ * We use pragma push_macro/pop_macro to keep the namespace clean. */
3422
+ # pragma push_macro("bool")
3423
+ # pragma push_macro("vector")
3424
+ # pragma push_macro("pixel")
3425
+ /* silence potential macro redefined warnings */
3426
+ # undef bool
3427
+ # undef vector
3428
+ # undef pixel
3429
+
3119
3430
  # if defined(__s390x__)
3120
3431
  # include <s390intrin.h>
3121
3432
  # else
3122
- /* gcc's altivec.h can have the unwanted consequence to unconditionally
3123
- * #define bool, vector, and pixel keywords,
3124
- * with bad consequences for programs already using these keywords for other purposes.
3125
- * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined.
3126
- * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler,
3127
- * but it seems that, in some cases, it isn't.
3128
- * Force the build macro to be defined, so that keywords are not altered.
3129
- */
3130
- # if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__)
3131
- # define __APPLE_ALTIVEC__
3132
- # endif
3133
3433
  # include <altivec.h>
3134
3434
  # endif
3135
3435
 
3436
+ /* Restore the original macro values, if applicable. */
3437
+ # pragma pop_macro("pixel")
3438
+ # pragma pop_macro("vector")
3439
+ # pragma pop_macro("bool")
3440
+
3136
3441
  typedef __vector unsigned long long xxh_u64x2;
3137
3442
  typedef __vector unsigned char xxh_u8x16;
3138
3443
  typedef __vector unsigned xxh_u32x4;
@@ -3188,8 +3493,9 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr)
3188
3493
  /* s390x is always big endian, no issue on this platform */
3189
3494
  # define XXH_vec_mulo vec_mulo
3190
3495
  # define XXH_vec_mule vec_mule
3191
- # elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw)
3496
+ # elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) && !defined(__ibmxl__)
3192
3497
  /* Clang has a better way to control this, we can just use the builtin which doesn't swap. */
3498
+ /* The IBM XL Compiler (which defined __clang__) only implements the vec_* operations */
3193
3499
  # define XXH_vec_mulo __builtin_altivec_vmulouw
3194
3500
  # define XXH_vec_mule __builtin_altivec_vmuleuw
3195
3501
  # else
@@ -3216,7 +3522,9 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b)
3216
3522
  #if defined(XXH_NO_PREFETCH)
3217
3523
  # define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */
3218
3524
  #else
3219
- # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */
3525
+ # if XXH_SIZE_OPT >= 1
3526
+ # define XXH_PREFETCH(ptr) (void)(ptr)
3527
+ # elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */
3220
3528
  # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
3221
3529
  # define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
3222
3530
  # elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
@@ -3444,7 +3752,7 @@ XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs)
3444
3752
  }
3445
3753
 
3446
3754
  /*! Seems to produce slightly better code on GCC for some reason. */
3447
- XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
3755
+ XXH_FORCE_INLINE XXH_CONSTF xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
3448
3756
  {
3449
3757
  XXH_ASSERT(0 <= shift && shift < 64);
3450
3758
  return v64 ^ (v64 >> shift);
@@ -3511,7 +3819,7 @@ static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len)
3511
3819
  *
3512
3820
  * This adds an extra layer of strength for custom secrets.
3513
3821
  */
3514
- XXH_FORCE_INLINE XXH64_hash_t
3822
+ XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
3515
3823
  XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3516
3824
  {
3517
3825
  XXH_ASSERT(input != NULL);
@@ -3533,7 +3841,7 @@ XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_h
3533
3841
  }
3534
3842
  }
3535
3843
 
3536
- XXH_FORCE_INLINE XXH64_hash_t
3844
+ XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
3537
3845
  XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3538
3846
  {
3539
3847
  XXH_ASSERT(input != NULL);
@@ -3549,7 +3857,7 @@ XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_h
3549
3857
  }
3550
3858
  }
3551
3859
 
3552
- XXH_FORCE_INLINE XXH64_hash_t
3860
+ XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
3553
3861
  XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3554
3862
  {
3555
3863
  XXH_ASSERT(input != NULL);
@@ -3566,7 +3874,7 @@ XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_
3566
3874
  }
3567
3875
  }
3568
3876
 
3569
- XXH_FORCE_INLINE XXH64_hash_t
3877
+ XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
3570
3878
  XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3571
3879
  {
3572
3880
  XXH_ASSERT(len <= 16);
@@ -3636,7 +3944,7 @@ XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input,
3636
3944
  }
3637
3945
 
3638
3946
  /* For mid range keys, XXH3 uses a Mum-hash variant. */
3639
- XXH_FORCE_INLINE XXH64_hash_t
3947
+ XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
3640
3948
  XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
3641
3949
  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
3642
3950
  XXH64_hash_t seed)
@@ -3645,6 +3953,14 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
3645
3953
  XXH_ASSERT(16 < len && len <= 128);
3646
3954
 
3647
3955
  { xxh_u64 acc = len * XXH_PRIME64_1;
3956
+ #if XXH_SIZE_OPT >= 1
3957
+ /* Smaller and cleaner, but slightly slower. */
3958
+ size_t i = (len - 1) / 32;
3959
+ do {
3960
+ acc += XXH3_mix16B(input+16 * i, secret+32*i, seed);
3961
+ acc += XXH3_mix16B(input+len-16*(i+1), secret+32*i+16, seed);
3962
+ } while (i-- != 0);
3963
+ #else
3648
3964
  if (len > 32) {
3649
3965
  if (len > 64) {
3650
3966
  if (len > 96) {
@@ -3659,14 +3975,14 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
3659
3975
  }
3660
3976
  acc += XXH3_mix16B(input+0, secret+0, seed);
3661
3977
  acc += XXH3_mix16B(input+len-16, secret+16, seed);
3662
-
3978
+ #endif
3663
3979
  return XXH3_avalanche(acc);
3664
3980
  }
3665
3981
  }
3666
3982
 
3667
3983
  #define XXH3_MIDSIZE_MAX 240
3668
3984
 
3669
- XXH_NO_INLINE XXH64_hash_t
3985
+ XXH_NO_INLINE XXH_PUREF XXH64_hash_t
3670
3986
  XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
3671
3987
  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
3672
3988
  XXH64_hash_t seed)
@@ -4332,7 +4648,7 @@ XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc,
4332
4648
  #if defined(__GNUC__) && !defined(__clang__) \
4333
4649
  && (defined(__arm__) || defined(__thumb2__)) \
4334
4650
  && defined(__ARM_FEATURE_UNALIGNED) /* no unaligned access just wastes bytes */ \
4335
- && !defined(__OPTIMIZE_SIZE__)
4651
+ && XXH_SIZE_OPT <= 0
4336
4652
  # pragma GCC unroll 8
4337
4653
  #endif
4338
4654
  for (i=0; i < XXH_ACC_NB; i++) {
@@ -4491,7 +4807,10 @@ typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64);
4491
4807
 
4492
4808
  #endif
4493
4809
 
4494
-
4810
+ #if XXH_SIZE_OPT >= 1 /* don't do SIMD for initialization */
4811
+ # undef XXH3_initCustomSecret
4812
+ # define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
4813
+ #endif
4495
4814
 
4496
4815
  #ifndef XXH_PREFETCH_DIST
4497
4816
  # ifdef __clang__
@@ -4635,7 +4954,7 @@ XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len,
4635
4954
  * Note that inside this no_inline function, we do inline the internal loop,
4636
4955
  * and provide a statically defined secret size to allow optimization of vector loop.
4637
4956
  */
4638
- XXH_NO_INLINE XXH64_hash_t
4957
+ XXH_NO_INLINE XXH_PUREF XXH64_hash_t
4639
4958
  XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len,
4640
4959
  XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
4641
4960
  {
@@ -4661,10 +4980,12 @@ XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len,
4661
4980
  XXH3_f_scrambleAcc f_scramble,
4662
4981
  XXH3_f_initCustomSecret f_initSec)
4663
4982
  {
4983
+ #if XXH_SIZE_OPT <= 0
4664
4984
  if (seed == 0)
4665
4985
  return XXH3_hashLong_64b_internal(input, len,
4666
4986
  XXH3_kSecret, sizeof(XXH3_kSecret),
4667
4987
  f_acc512, f_scramble);
4988
+ #endif
4668
4989
  { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
4669
4990
  f_initSec(secret, seed);
4670
4991
  return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret),
@@ -4713,37 +5034,37 @@ XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len,
4713
5034
 
4714
5035
  /* === Public entry point === */
4715
5036
 
4716
- /*! @ingroup xxh3_family */
4717
- XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len)
5037
+ /*! @ingroup XXH3_family */
5038
+ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t length)
4718
5039
  {
4719
- return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default);
5040
+ return XXH3_64bits_internal(input, length, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default);
4720
5041
  }
4721
5042
 
4722
- /*! @ingroup xxh3_family */
5043
+ /*! @ingroup XXH3_family */
4723
5044
  XXH_PUBLIC_API XXH64_hash_t
4724
- XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
5045
+ XXH3_64bits_withSecret(const void* input, size_t length, const void* secret, size_t secretSize)
4725
5046
  {
4726
- return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret);
5047
+ return XXH3_64bits_internal(input, length, 0, secret, secretSize, XXH3_hashLong_64b_withSecret);
4727
5048
  }
4728
5049
 
4729
- /*! @ingroup xxh3_family */
5050
+ /*! @ingroup XXH3_family */
4730
5051
  XXH_PUBLIC_API XXH64_hash_t
4731
- XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
5052
+ XXH3_64bits_withSeed(const void* input, size_t length, XXH64_hash_t seed)
4732
5053
  {
4733
- return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed);
5054
+ return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed);
4734
5055
  }
4735
5056
 
4736
5057
  XXH_PUBLIC_API XXH64_hash_t
4737
- XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
5058
+ XXH3_64bits_withSecretandSeed(const void* input, size_t length, const void* secret, size_t secretSize, XXH64_hash_t seed)
4738
5059
  {
4739
- if (len <= XXH3_MIDSIZE_MAX)
4740
- return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
4741
- return XXH3_hashLong_64b_withSecret(input, len, seed, (const xxh_u8*)secret, secretSize);
5060
+ if (length <= XXH3_MIDSIZE_MAX)
5061
+ return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
5062
+ return XXH3_hashLong_64b_withSecret(input, length, seed, (const xxh_u8*)secret, secretSize);
4742
5063
  }
4743
5064
 
4744
5065
 
4745
5066
  /* === XXH3 streaming === */
4746
-
5067
+ #ifndef XXH_NO_STREAM
4747
5068
  /*
4748
5069
  * Malloc's a pointer that is always aligned to align.
4749
5070
  *
@@ -4767,7 +5088,7 @@ XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret,
4767
5088
  *
4768
5089
  * Align must be a power of 2 and 8 <= align <= 128.
4769
5090
  */
4770
- static void* XXH_alignedMalloc(size_t s, size_t align)
5091
+ static XXH_MALLOCF void* XXH_alignedMalloc(size_t s, size_t align)
4771
5092
  {
4772
5093
  XXH_ASSERT(align <= 128 && align >= 8); /* range check */
4773
5094
  XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */
@@ -4809,7 +5130,7 @@ static void XXH_alignedFree(void* p)
4809
5130
  XXH_free(base);
4810
5131
  }
4811
5132
  }
4812
- /*! @ingroup xxh3_family */
5133
+ /*! @ingroup XXH3_family */
4813
5134
  XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
4814
5135
  {
4815
5136
  XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64);
@@ -4818,14 +5139,14 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
4818
5139
  return state;
4819
5140
  }
4820
5141
 
4821
- /*! @ingroup xxh3_family */
5142
+ /*! @ingroup XXH3_family */
4822
5143
  XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr)
4823
5144
  {
4824
5145
  XXH_alignedFree(statePtr);
4825
5146
  return XXH_OK;
4826
5147
  }
4827
5148
 
4828
- /*! @ingroup xxh3_family */
5149
+ /*! @ingroup XXH3_family */
4829
5150
  XXH_PUBLIC_API void
4830
5151
  XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state)
4831
5152
  {
@@ -4859,7 +5180,7 @@ XXH3_reset_internal(XXH3_state_t* statePtr,
4859
5180
  statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE;
4860
5181
  }
4861
5182
 
4862
- /*! @ingroup xxh3_family */
5183
+ /*! @ingroup XXH3_family */
4863
5184
  XXH_PUBLIC_API XXH_errorcode
4864
5185
  XXH3_64bits_reset(XXH3_state_t* statePtr)
4865
5186
  {
@@ -4868,7 +5189,7 @@ XXH3_64bits_reset(XXH3_state_t* statePtr)
4868
5189
  return XXH_OK;
4869
5190
  }
4870
5191
 
4871
- /*! @ingroup xxh3_family */
5192
+ /*! @ingroup XXH3_family */
4872
5193
  XXH_PUBLIC_API XXH_errorcode
4873
5194
  XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
4874
5195
  {
@@ -4879,7 +5200,7 @@ XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t
4879
5200
  return XXH_OK;
4880
5201
  }
4881
5202
 
4882
- /*! @ingroup xxh3_family */
5203
+ /*! @ingroup XXH3_family */
4883
5204
  XXH_PUBLIC_API XXH_errorcode
4884
5205
  XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
4885
5206
  {
@@ -4891,7 +5212,7 @@ XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
4891
5212
  return XXH_OK;
4892
5213
  }
4893
5214
 
4894
- /*! @ingroup xxh3_family */
5215
+ /*! @ingroup XXH3_family */
4895
5216
  XXH_PUBLIC_API XXH_errorcode
4896
5217
  XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64)
4897
5218
  {
@@ -4931,7 +5252,7 @@ XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc,
4931
5252
  }
4932
5253
 
4933
5254
  #ifndef XXH3_STREAM_USE_STACK
4934
- # ifndef __clang__ /* clang doesn't need additional stack space */
5255
+ # if XXH_SIZE_OPT <= 0 && !defined(__clang__) /* clang doesn't need additional stack space */
4935
5256
  # define XXH3_STREAM_USE_STACK 1
4936
5257
  # endif
4937
5258
  #endif
@@ -5053,7 +5374,7 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state,
5053
5374
  return XXH_OK;
5054
5375
  }
5055
5376
 
5056
- /*! @ingroup xxh3_family */
5377
+ /*! @ingroup XXH3_family */
5057
5378
  XXH_PUBLIC_API XXH_errorcode
5058
5379
  XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len)
5059
5380
  {
@@ -5096,7 +5417,7 @@ XXH3_digest_long (XXH64_hash_t* acc,
5096
5417
  }
5097
5418
  }
5098
5419
 
5099
- /*! @ingroup xxh3_family */
5420
+ /*! @ingroup XXH3_family */
5100
5421
  XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
5101
5422
  {
5102
5423
  const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
@@ -5113,7 +5434,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
5113
5434
  return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen),
5114
5435
  secret, state->secretLimit + XXH_STRIPE_LEN);
5115
5436
  }
5116
-
5437
+ #endif /* !XXH_NO_STREAM */
5117
5438
 
5118
5439
 
5119
5440
  /* ==========================================
@@ -5133,7 +5454,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
5133
5454
  * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64).
5134
5455
  */
5135
5456
 
5136
- XXH_FORCE_INLINE XXH128_hash_t
5457
+ XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
5137
5458
  XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5138
5459
  {
5139
5460
  /* A doubled version of 1to3_64b with different constants. */
@@ -5162,7 +5483,7 @@ XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_
5162
5483
  }
5163
5484
  }
5164
5485
 
5165
- XXH_FORCE_INLINE XXH128_hash_t
5486
+ XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
5166
5487
  XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5167
5488
  {
5168
5489
  XXH_ASSERT(input != NULL);
@@ -5189,7 +5510,7 @@ XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_
5189
5510
  }
5190
5511
  }
5191
5512
 
5192
- XXH_FORCE_INLINE XXH128_hash_t
5513
+ XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
5193
5514
  XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5194
5515
  {
5195
5516
  XXH_ASSERT(input != NULL);
@@ -5264,7 +5585,7 @@ XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64
5264
5585
  /*
5265
5586
  * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN
5266
5587
  */
5267
- XXH_FORCE_INLINE XXH128_hash_t
5588
+ XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
5268
5589
  XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5269
5590
  {
5270
5591
  XXH_ASSERT(len <= 16);
@@ -5295,7 +5616,7 @@ XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2,
5295
5616
  }
5296
5617
 
5297
5618
 
5298
- XXH_FORCE_INLINE XXH128_hash_t
5619
+ XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
5299
5620
  XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
5300
5621
  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
5301
5622
  XXH64_hash_t seed)
@@ -5306,6 +5627,16 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
5306
5627
  { XXH128_hash_t acc;
5307
5628
  acc.low64 = len * XXH_PRIME64_1;
5308
5629
  acc.high64 = 0;
5630
+
5631
+ #if XXH_SIZE_OPT >= 1
5632
+ {
5633
+ /* Smaller, but slightly slower. */
5634
+ size_t i = (len - 1) / 32;
5635
+ do {
5636
+ acc = XXH128_mix32B(acc, input+16*i, input+len-16*(i+1), secret+32*i, seed);
5637
+ } while (i-- != 0);
5638
+ }
5639
+ #else
5309
5640
  if (len > 32) {
5310
5641
  if (len > 64) {
5311
5642
  if (len > 96) {
@@ -5316,6 +5647,7 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
5316
5647
  acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed);
5317
5648
  }
5318
5649
  acc = XXH128_mix32B(acc, input, input+len-16, secret, seed);
5650
+ #endif
5319
5651
  { XXH128_hash_t h128;
5320
5652
  h128.low64 = acc.low64 + acc.high64;
5321
5653
  h128.high64 = (acc.low64 * XXH_PRIME64_1)
@@ -5328,7 +5660,7 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
5328
5660
  }
5329
5661
  }
5330
5662
 
5331
- XXH_NO_INLINE XXH128_hash_t
5663
+ XXH_NO_INLINE XXH_PUREF XXH128_hash_t
5332
5664
  XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
5333
5665
  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
5334
5666
  XXH64_hash_t seed)
@@ -5403,9 +5735,9 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len,
5403
5735
  }
5404
5736
 
5405
5737
  /*
5406
- * It's important for performance that XXH3_hashLong is not inlined.
5738
+ * It's important for performance that XXH3_hashLong() is not inlined.
5407
5739
  */
5408
- XXH_NO_INLINE XXH128_hash_t
5740
+ XXH_NO_INLINE XXH_PUREF XXH128_hash_t
5409
5741
  XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len,
5410
5742
  XXH64_hash_t seed64,
5411
5743
  const void* XXH_RESTRICT secret, size_t secretLen)
@@ -5416,7 +5748,7 @@ XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len,
5416
5748
  }
5417
5749
 
5418
5750
  /*
5419
- * It's important for performance to pass @secretLen (when it's static)
5751
+ * It's important for performance to pass @p secretLen (when it's static)
5420
5752
  * to the compiler, so that it can properly optimize the vectorized loop.
5421
5753
  */
5422
5754
  XXH_FORCE_INLINE XXH128_hash_t
@@ -5486,7 +5818,7 @@ XXH3_128bits_internal(const void* input, size_t len,
5486
5818
 
5487
5819
  /* === Public XXH128 API === */
5488
5820
 
5489
- /*! @ingroup xxh3_family */
5821
+ /*! @ingroup XXH3_family */
5490
5822
  XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len)
5491
5823
  {
5492
5824
  return XXH3_128bits_internal(input, len, 0,
@@ -5494,7 +5826,7 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len)
5494
5826
  XXH3_hashLong_128b_default);
5495
5827
  }
5496
5828
 
5497
- /*! @ingroup xxh3_family */
5829
+ /*! @ingroup XXH3_family */
5498
5830
  XXH_PUBLIC_API XXH128_hash_t
5499
5831
  XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
5500
5832
  {
@@ -5503,7 +5835,7 @@ XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_
5503
5835
  XXH3_hashLong_128b_withSecret);
5504
5836
  }
5505
5837
 
5506
- /*! @ingroup xxh3_family */
5838
+ /*! @ingroup XXH3_family */
5507
5839
  XXH_PUBLIC_API XXH128_hash_t
5508
5840
  XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
5509
5841
  {
@@ -5512,7 +5844,7 @@ XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
5512
5844
  XXH3_hashLong_128b_withSeed);
5513
5845
  }
5514
5846
 
5515
- /*! @ingroup xxh3_family */
5847
+ /*! @ingroup XXH3_family */
5516
5848
  XXH_PUBLIC_API XXH128_hash_t
5517
5849
  XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
5518
5850
  {
@@ -5521,7 +5853,7 @@ XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret
5521
5853
  return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize);
5522
5854
  }
5523
5855
 
5524
- /*! @ingroup xxh3_family */
5856
+ /*! @ingroup XXH3_family */
5525
5857
  XXH_PUBLIC_API XXH128_hash_t
5526
5858
  XXH128(const void* input, size_t len, XXH64_hash_t seed)
5527
5859
  {
@@ -5530,41 +5862,41 @@ XXH128(const void* input, size_t len, XXH64_hash_t seed)
5530
5862
 
5531
5863
 
5532
5864
  /* === XXH3 128-bit streaming === */
5533
-
5865
+ #ifndef XXH_NO_STREAM
5534
5866
  /*
5535
5867
  * All initialization and update functions are identical to 64-bit streaming variant.
5536
5868
  * The only difference is the finalization routine.
5537
5869
  */
5538
5870
 
5539
- /*! @ingroup xxh3_family */
5871
+ /*! @ingroup XXH3_family */
5540
5872
  XXH_PUBLIC_API XXH_errorcode
5541
5873
  XXH3_128bits_reset(XXH3_state_t* statePtr)
5542
5874
  {
5543
5875
  return XXH3_64bits_reset(statePtr);
5544
5876
  }
5545
5877
 
5546
- /*! @ingroup xxh3_family */
5878
+ /*! @ingroup XXH3_family */
5547
5879
  XXH_PUBLIC_API XXH_errorcode
5548
5880
  XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
5549
5881
  {
5550
5882
  return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize);
5551
5883
  }
5552
5884
 
5553
- /*! @ingroup xxh3_family */
5885
+ /*! @ingroup XXH3_family */
5554
5886
  XXH_PUBLIC_API XXH_errorcode
5555
5887
  XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
5556
5888
  {
5557
5889
  return XXH3_64bits_reset_withSeed(statePtr, seed);
5558
5890
  }
5559
5891
 
5560
- /*! @ingroup xxh3_family */
5892
+ /*! @ingroup XXH3_family */
5561
5893
  XXH_PUBLIC_API XXH_errorcode
5562
5894
  XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed)
5563
5895
  {
5564
5896
  return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed);
5565
5897
  }
5566
5898
 
5567
- /*! @ingroup xxh3_family */
5899
+ /*! @ingroup XXH3_family */
5568
5900
  XXH_PUBLIC_API XXH_errorcode
5569
5901
  XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len)
5570
5902
  {
@@ -5572,7 +5904,7 @@ XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len)
5572
5904
  XXH3_accumulate_512, XXH3_scrambleAcc);
5573
5905
  }
5574
5906
 
5575
- /*! @ingroup xxh3_family */
5907
+ /*! @ingroup XXH3_family */
5576
5908
  XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state)
5577
5909
  {
5578
5910
  const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
@@ -5597,13 +5929,13 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state)
5597
5929
  return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen),
5598
5930
  secret, state->secretLimit + XXH_STRIPE_LEN);
5599
5931
  }
5600
-
5932
+ #endif /* !XXH_NO_STREAM */
5601
5933
  /* 128-bit utility functions */
5602
5934
 
5603
5935
  #include <string.h> /* memcmp, memcpy */
5604
5936
 
5605
5937
  /* return : 1 is equal, 0 if different */
5606
- /*! @ingroup xxh3_family */
5938
+ /*! @ingroup XXH3_family */
5607
5939
  XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
5608
5940
  {
5609
5941
  /* note : XXH128_hash_t is compact, it has no padding byte */
@@ -5611,10 +5943,10 @@ XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
5611
5943
  }
5612
5944
 
5613
5945
  /* This prototype is compatible with stdlib's qsort().
5614
- * return : >0 if *h128_1 > *h128_2
5615
- * <0 if *h128_1 < *h128_2
5616
- * =0 if *h128_1 == *h128_2 */
5617
- /*! @ingroup xxh3_family */
5946
+ * @return : >0 if *h128_1 > *h128_2
5947
+ * <0 if *h128_1 < *h128_2
5948
+ * =0 if *h128_1 == *h128_2 */
5949
+ /*! @ingroup XXH3_family */
5618
5950
  XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2)
5619
5951
  {
5620
5952
  XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1;
@@ -5627,7 +5959,7 @@ XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2)
5627
5959
 
5628
5960
 
5629
5961
  /*====== Canonical representation ======*/
5630
- /*! @ingroup xxh3_family */
5962
+ /*! @ingroup XXH3_family */
5631
5963
  XXH_PUBLIC_API void
5632
5964
  XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash)
5633
5965
  {
@@ -5640,7 +5972,7 @@ XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash)
5640
5972
  XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64));
5641
5973
  }
5642
5974
 
5643
- /*! @ingroup xxh3_family */
5975
+ /*! @ingroup XXH3_family */
5644
5976
  XXH_PUBLIC_API XXH128_hash_t
5645
5977
  XXH128_hashFromCanonical(const XXH128_canonical_t* src)
5646
5978
  {
@@ -5664,7 +5996,7 @@ XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128)
5664
5996
  XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 );
5665
5997
  }
5666
5998
 
5667
- /*! @ingroup xxh3_family */
5999
+ /*! @ingroup XXH3_family */
5668
6000
  XXH_PUBLIC_API XXH_errorcode
5669
6001
  XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize)
5670
6002
  {
@@ -5709,7 +6041,7 @@ XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSee
5709
6041
  return XXH_OK;
5710
6042
  }
5711
6043
 
5712
- /*! @ingroup xxh3_family */
6044
+ /*! @ingroup XXH3_family */
5713
6045
  XXH_PUBLIC_API void
5714
6046
  XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed)
5715
6047
  {
@@ -5724,7 +6056,7 @@ XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed)
5724
6056
  /* Pop our optimization override from above */
5725
6057
  #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
5726
6058
  && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
5727
- && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
6059
+ && defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0 /* respect -O0 and -Os */
5728
6060
  # pragma GCC pop_options
5729
6061
  #endif
5730
6062