digest-xxhash 0.2.2 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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