digest-xxhash 0.2.2 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/Rakefile +13 -14
- data/digest-xxhash.gemspec +20 -3
- data/ext/digest/xxhash/xxhash.h +701 -369
- data/lib/digest/xxhash/version.rb +1 -1
- data/rakelib/alt-install-task.rake +58 -0
- metadata +4 -3
data/ext/digest/xxhash/xxhash.h
CHANGED
@@ -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
|
-
*
|
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
|
-
*
|
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
|
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
|
-
|
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
|
-
#
|
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
|
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
|
386
|
-
*
|
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
|
389
|
-
* @see @ref
|
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
|
-
*
|
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
|
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(
|
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__ ((
|
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
|
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
|
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
|
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
|
-
*
|
757
|
-
*
|
758
|
-
*
|
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
|
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
|
-
|
783
|
-
*
|
784
|
-
*
|
785
|
-
|
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
|
-
*
|
789
|
-
*
|
790
|
-
*
|
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
|
-
*
|
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*
|
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
|
-
*
|
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
|
-
|
889
|
-
|
890
|
-
|
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
|
-
*
|
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
|
-
*
|
929
|
-
*
|
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.
|
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
|
-
|
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
|
1136
|
-
* as it becomes much more difficult for an external actor to
|
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
|
-
*
|
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
|
-
*
|
1145
|
-
*
|
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
|
-
*
|
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
|
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
|
-
*
|
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
|
-
*
|
1172
|
-
*
|
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
|
-
*
|
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*
|
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
|
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
|
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),
|
1380
|
-
*
|
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
|
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(
|
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
|
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) {
|
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
|
-
#
|
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
|
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
|
2230
|
+
* @param hash The hash to avalanche.
|
1963
2231
|
* @return The avalanched hash.
|
1964
2232
|
*/
|
1965
|
-
static xxh_u32 XXH32_avalanche(xxh_u32
|
2233
|
+
static xxh_u32 XXH32_avalanche(xxh_u32 hash)
|
1966
2234
|
{
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
return
|
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
|
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
|
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
|
-
|
1996
|
-
|
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
|
-
|
2001
|
-
ptr += 4;
|
2002
|
-
|
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(
|
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(
|
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(
|
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(
|
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(
|
2326
|
+
case 0: return XXH32_avalanche(hash);
|
2058
2327
|
}
|
2059
2328
|
XXH_ASSERT(0);
|
2060
|
-
return
|
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
|
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
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
2715
|
+
/*! @copydoc XXH32_avalanche */
|
2716
|
+
static xxh_u64 XXH64_avalanche(xxh_u64 hash)
|
2445
2717
|
{
|
2446
|
-
|
2447
|
-
|
2448
|
-
|
2449
|
-
|
2450
|
-
|
2451
|
-
return
|
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
|
-
|
2458
|
-
|
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
|
-
|
2466
|
-
|
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
|
-
|
2757
|
+
hash ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1;
|
2471
2758
|
ptr += 4;
|
2472
|
-
|
2759
|
+
hash = XXH_rotl64(hash, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
|
2473
2760
|
len -= 4;
|
2474
2761
|
}
|
2475
2762
|
while (len > 0) {
|
2476
|
-
|
2477
|
-
|
2763
|
+
hash ^= (*ptr++) * XXH_PRIME64_5;
|
2764
|
+
hash = XXH_rotl64(hash, 11) * XXH_PRIME64_1;
|
2478
2765
|
--len;
|
2479
2766
|
}
|
2480
|
-
return XXH64_avalanche(
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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__) &&
|
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
|
-
&&
|
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
|
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
|
-
&&
|
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
|
4717
|
-
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t
|
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,
|
5040
|
+
return XXH3_64bits_internal(input, length, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default);
|
4720
5041
|
}
|
4721
5042
|
|
4722
|
-
/*! @ingroup
|
5043
|
+
/*! @ingroup XXH3_family */
|
4723
5044
|
XXH_PUBLIC_API XXH64_hash_t
|
4724
|
-
XXH3_64bits_withSecret(const void* input, size_t
|
5045
|
+
XXH3_64bits_withSecret(const void* input, size_t length, const void* secret, size_t secretSize)
|
4725
5046
|
{
|
4726
|
-
return XXH3_64bits_internal(input,
|
5047
|
+
return XXH3_64bits_internal(input, length, 0, secret, secretSize, XXH3_hashLong_64b_withSecret);
|
4727
5048
|
}
|
4728
5049
|
|
4729
|
-
/*! @ingroup
|
5050
|
+
/*! @ingroup XXH3_family */
|
4730
5051
|
XXH_PUBLIC_API XXH64_hash_t
|
4731
|
-
XXH3_64bits_withSeed(const void* input, size_t
|
5052
|
+
XXH3_64bits_withSeed(const void* input, size_t length, XXH64_hash_t seed)
|
4732
5053
|
{
|
4733
|
-
return XXH3_64bits_internal(input,
|
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
|
5058
|
+
XXH3_64bits_withSecretandSeed(const void* input, size_t length, const void* secret, size_t secretSize, XXH64_hash_t seed)
|
4738
5059
|
{
|
4739
|
-
if (
|
4740
|
-
return XXH3_64bits_internal(input,
|
4741
|
-
return XXH3_hashLong_64b_withSecret(input,
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
#
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
*
|
5616
|
-
*
|
5617
|
-
/*! @ingroup
|
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
|
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
|
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
|
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
|
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__) &&
|
6059
|
+
&& defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0 /* respect -O0 and -Os */
|
5728
6060
|
# pragma GCC pop_options
|
5729
6061
|
#endif
|
5730
6062
|
|