digest-xxhash 0.2.2 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|