digest-xxhash 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +13 -14
- data/digest-xxhash.gemspec +20 -3
- data/ext/digest/xxhash/xxhash.h +565 -331
- data/lib/digest/xxhash/version.rb +1 -1
- data/rakelib/alt-install-task.rake +59 -0
- metadata +3 -2
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,7 +545,7 @@ 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
|
|
417
550
|
/*!
|
418
551
|
* Streaming functions generate the xxHash value from an incremental input.
|
@@ -436,32 +569,7 @@ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_
|
|
436
569
|
*
|
437
570
|
* When done, release the state using `XXH*_freeState()`.
|
438
571
|
*
|
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
|
572
|
+
* @see streaming_example at the top of @ref xxhash.h for an example.
|
465
573
|
*/
|
466
574
|
|
467
575
|
/*!
|
@@ -478,7 +586,7 @@ typedef struct XXH32_state_s XXH32_state_t;
|
|
478
586
|
* Must be freed with XXH32_freeState().
|
479
587
|
* @return An allocated XXH32_state_t on success, `NULL` on failure.
|
480
588
|
*/
|
481
|
-
XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
|
589
|
+
XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void);
|
482
590
|
/*!
|
483
591
|
* @brief Frees an @ref XXH32_state_t.
|
484
592
|
*
|
@@ -546,7 +654,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void*
|
|
546
654
|
*
|
547
655
|
* @return The calculated xxHash32 value from that state.
|
548
656
|
*/
|
549
|
-
XXH_PUBLIC_API XXH32_hash_t
|
657
|
+
XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
|
550
658
|
|
551
659
|
/******* Canonical representation *******/
|
552
660
|
|
@@ -597,7 +705,7 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t
|
|
597
705
|
*
|
598
706
|
* @return The converted hash.
|
599
707
|
*/
|
600
|
-
XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
|
708
|
+
XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
|
601
709
|
|
602
710
|
|
603
711
|
#ifdef __has_attribute
|
@@ -620,19 +728,17 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src
|
|
620
728
|
#endif
|
621
729
|
|
622
730
|
/*
|
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)
|
731
|
+
* Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute
|
732
|
+
* introduced in CPP17 and C23.
|
733
|
+
* CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough
|
734
|
+
* C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough
|
735
|
+
*/
|
736
|
+
#if XXH_HAS_C_ATTRIBUTE(fallthrough) || XXH_HAS_CPP_ATTRIBUTE(fallthrough)
|
631
737
|
# define XXH_FALLTHROUGH [[fallthrough]]
|
632
738
|
#elif XXH_HAS_ATTRIBUTE(__fallthrough__)
|
633
|
-
# define XXH_FALLTHROUGH __attribute__ ((
|
739
|
+
# define XXH_FALLTHROUGH __attribute__ ((__fallthrough__))
|
634
740
|
#else
|
635
|
-
# define XXH_FALLTHROUGH
|
741
|
+
# define XXH_FALLTHROUGH /* fallthrough */
|
636
742
|
#endif
|
637
743
|
|
638
744
|
/*!
|
@@ -671,7 +777,7 @@ typedef uint64_t XXH64_hash_t;
|
|
671
777
|
/*!
|
672
778
|
* @}
|
673
779
|
*
|
674
|
-
* @defgroup
|
780
|
+
* @defgroup XXH64_family XXH64 family
|
675
781
|
* @ingroup public
|
676
782
|
* @{
|
677
783
|
* Contains functions used in the classic 64-bit xxHash algorithm.
|
@@ -682,7 +788,6 @@ typedef uint64_t XXH64_hash_t;
|
|
682
788
|
* It provides better speed for systems with vector processing capabilities.
|
683
789
|
*/
|
684
790
|
|
685
|
-
|
686
791
|
/*!
|
687
792
|
* @brief Calculates the 64-bit hash of @p input using xxHash64.
|
688
793
|
*
|
@@ -706,7 +811,7 @@ typedef uint64_t XXH64_hash_t;
|
|
706
811
|
* @see
|
707
812
|
* XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version.
|
708
813
|
*/
|
709
|
-
XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed);
|
814
|
+
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed);
|
710
815
|
|
711
816
|
/******* Streaming *******/
|
712
817
|
/*!
|
@@ -715,25 +820,25 @@ XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t
|
|
715
820
|
* @see XXH64_state_s for details.
|
716
821
|
*/
|
717
822
|
typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
|
718
|
-
XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
|
823
|
+
XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void);
|
719
824
|
XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
|
720
825
|
XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
|
721
826
|
|
722
827
|
XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed);
|
723
828
|
XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
|
724
|
-
XXH_PUBLIC_API XXH64_hash_t
|
829
|
+
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
|
725
830
|
|
726
831
|
/******* Canonical representation *******/
|
727
832
|
typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t;
|
728
833
|
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);
|
834
|
+
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
|
730
835
|
|
731
836
|
#ifndef XXH_NO_XXH3
|
732
837
|
|
733
838
|
/*!
|
734
839
|
* @}
|
735
840
|
* ************************************************************************
|
736
|
-
* @defgroup
|
841
|
+
* @defgroup XXH3_family XXH3 family
|
737
842
|
* @ingroup public
|
738
843
|
* @{
|
739
844
|
*
|
@@ -753,12 +858,14 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src
|
|
753
858
|
*
|
754
859
|
* XXH3's speed benefits greatly from SIMD and 64-bit arithmetic,
|
755
860
|
* but does not require it.
|
756
|
-
*
|
757
|
-
*
|
758
|
-
*
|
861
|
+
* Most 32-bit and 64-bit targets that can run XXH32 smoothly can run XXH3
|
862
|
+
* at competitive speeds, even without vector support. Further details are
|
863
|
+
* explained in the implementation.
|
759
864
|
*
|
760
865
|
* Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8,
|
761
|
-
* ZVector and scalar targets. This can be controlled via the XXH_VECTOR
|
866
|
+
* ZVector and scalar targets. This can be controlled via the @ref XXH_VECTOR
|
867
|
+
* macro. For the x86 family, an automatic dispatcher is included separately
|
868
|
+
* in @ref xxh_x86dispatch.c.
|
762
869
|
*
|
763
870
|
* XXH3 implementation is portable:
|
764
871
|
* it has a generic C90 formulation that can be compiled on any platform,
|
@@ -774,24 +881,42 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src
|
|
774
881
|
*
|
775
882
|
* The API supports one-shot hashing, streaming mode, and custom secrets.
|
776
883
|
*/
|
777
|
-
|
778
884
|
/*-**********************************************************************
|
779
885
|
* XXH3 64-bit variant
|
780
886
|
************************************************************************/
|
781
887
|
|
782
|
-
|
783
|
-
*
|
784
|
-
*
|
785
|
-
|
888
|
+
/*!
|
889
|
+
* @brief 64-bit unseeded variant of XXH3.
|
890
|
+
*
|
891
|
+
* This is equivalent to @ref XXH3_64bits_withSeed() with a seed of 0, however
|
892
|
+
* it may have slightly better performance due to constant propagation of the
|
893
|
+
* defaults.
|
894
|
+
*
|
895
|
+
* @see
|
896
|
+
* XXH32(), XXH64(), XXH3_128bits(): equivalent for the other xxHash algorithms
|
897
|
+
* @see
|
898
|
+
* XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants
|
899
|
+
* @see
|
900
|
+
* XXH3_64bits_reset(), XXH3_64bits_update(), XXH3_64bits_digest(): Streaming version.
|
901
|
+
*/
|
902
|
+
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(const void* input, size_t length);
|
786
903
|
|
787
|
-
|
788
|
-
*
|
789
|
-
*
|
790
|
-
*
|
904
|
+
/*!
|
905
|
+
* @brief 64-bit seeded variant of XXH3
|
906
|
+
*
|
907
|
+
* This variant generates a custom secret on the fly based on default secret
|
908
|
+
* altered using the `seed` value.
|
909
|
+
*
|
791
910
|
* While this operation is decently fast, note that it's not completely free.
|
792
|
-
*
|
911
|
+
*
|
912
|
+
* @note
|
913
|
+
* seed == 0 produces the same results as @ref XXH3_64bits().
|
914
|
+
*
|
915
|
+
* @param input The data to hash
|
916
|
+
* @param length The length
|
917
|
+
* @param seed The 64-bit seed to alter the state.
|
793
918
|
*/
|
794
|
-
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void*
|
919
|
+
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(const void* input, size_t length, XXH64_hash_t seed);
|
795
920
|
|
796
921
|
/*!
|
797
922
|
* The bare minimum size for a custom secret.
|
@@ -802,8 +927,9 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X
|
|
802
927
|
*/
|
803
928
|
#define XXH3_SECRET_SIZE_MIN 136
|
804
929
|
|
805
|
-
|
806
|
-
*
|
930
|
+
/*!
|
931
|
+
* @brief 64-bit variant of XXH3 with a custom "secret".
|
932
|
+
*
|
807
933
|
* It's possible to provide any blob of bytes as a "secret" to generate the hash.
|
808
934
|
* This makes it more difficult for an external actor to prepare an intentional collision.
|
809
935
|
* The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN).
|
@@ -819,7 +945,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X
|
|
819
945
|
* This is not necessarily the case when using the blob of bytes directly
|
820
946
|
* because, when hashing _small_ inputs, only a portion of the secret is employed.
|
821
947
|
*/
|
822
|
-
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
|
948
|
+
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
|
823
949
|
|
824
950
|
|
825
951
|
/******* Streaming *******/
|
@@ -836,7 +962,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len,
|
|
836
962
|
* @see XXH3_state_s for details.
|
837
963
|
*/
|
838
964
|
typedef struct XXH3_state_s XXH3_state_t;
|
839
|
-
XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void);
|
965
|
+
XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void);
|
840
966
|
XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr);
|
841
967
|
XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state);
|
842
968
|
|
@@ -852,7 +978,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr);
|
|
852
978
|
* digest will be equivalent to `XXH3_64bits_withSeed()`.
|
853
979
|
*/
|
854
980
|
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
|
855
|
-
|
981
|
+
/*!
|
856
982
|
* XXH3_64bits_reset_withSecret():
|
857
983
|
* `secret` is referenced, it _must outlive_ the hash streaming session.
|
858
984
|
* Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`,
|
@@ -864,7 +990,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr,
|
|
864
990
|
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
|
865
991
|
|
866
992
|
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);
|
993
|
+
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr);
|
868
994
|
|
869
995
|
/* note : canonical representation of XXH3 is the same as XXH64
|
870
996
|
* since they both produce XXH64_hash_t values */
|
@@ -885,9 +1011,28 @@ typedef struct {
|
|
885
1011
|
XXH64_hash_t high64; /*!< `value >> 64` */
|
886
1012
|
} XXH128_hash_t;
|
887
1013
|
|
888
|
-
|
889
|
-
|
890
|
-
|
1014
|
+
/*!
|
1015
|
+
* @brief Unseeded 128-bit variant of XXH3
|
1016
|
+
*
|
1017
|
+
* The 128-bit variant of XXH3 has more strength, but it has a bit of overhead
|
1018
|
+
* for shorter inputs.
|
1019
|
+
*
|
1020
|
+
* This is equivalent to @ref XXH3_128bits_withSeed() with a seed of 0, however
|
1021
|
+
* it may have slightly better performance due to constant propagation of the
|
1022
|
+
* defaults.
|
1023
|
+
*
|
1024
|
+
* @see
|
1025
|
+
* XXH32(), XXH64(), XXH3_64bits(): equivalent for the other xxHash algorithms
|
1026
|
+
* @see
|
1027
|
+
* XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants
|
1028
|
+
* @see
|
1029
|
+
* XXH3_128bits_reset(), XXH3_128bits_update(), XXH3_128bits_digest(): Streaming version.
|
1030
|
+
*/
|
1031
|
+
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(const void* data, size_t len);
|
1032
|
+
/*! @brief Seeded 128-bit variant of XXH3. @see XXH3_64bits_withSeed(). */
|
1033
|
+
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
|
1034
|
+
/*! @brief Custom secret 128-bit variant of XXH3. @see XXH3_64bits_withSecret(). */
|
1035
|
+
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
|
891
1036
|
|
892
1037
|
/******* Streaming *******/
|
893
1038
|
/*
|
@@ -907,7 +1052,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr,
|
|
907
1052
|
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
|
908
1053
|
|
909
1054
|
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);
|
1055
|
+
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);
|
911
1056
|
|
912
1057
|
/* Following helper functions make it possible to compare XXH128_hast_t values.
|
913
1058
|
* Since XXH128_hash_t is a structure, this capability is not offered by the language.
|
@@ -917,24 +1062,23 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);
|
|
917
1062
|
* XXH128_isEqual():
|
918
1063
|
* Return: 1 if `h1` and `h2` are equal, 0 if they are not.
|
919
1064
|
*/
|
920
|
-
XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2);
|
1065
|
+
XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2);
|
921
1066
|
|
922
1067
|
/*!
|
923
|
-
*
|
924
|
-
*
|
1068
|
+
* @brief Compares two @ref XXH128_hash_t
|
925
1069
|
* This comparator is compatible with stdlib's `qsort()`/`bsearch()`.
|
926
1070
|
*
|
927
|
-
* return: >0 if *h128_1 > *h128_2
|
928
|
-
*
|
929
|
-
*
|
1071
|
+
* @return: >0 if *h128_1 > *h128_2
|
1072
|
+
* =0 if *h128_1 == *h128_2
|
1073
|
+
* <0 if *h128_1 < *h128_2
|
930
1074
|
*/
|
931
|
-
XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2);
|
1075
|
+
XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(const void* h128_1, const void* h128_2);
|
932
1076
|
|
933
1077
|
|
934
1078
|
/******* Canonical representation *******/
|
935
1079
|
typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t;
|
936
1080
|
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);
|
1081
|
+
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src);
|
938
1082
|
|
939
1083
|
|
940
1084
|
#endif /* !XXH_NO_XXH3 */
|
@@ -1075,7 +1219,7 @@ struct XXH64_state_s {
|
|
1075
1219
|
*/
|
1076
1220
|
struct XXH3_state_s {
|
1077
1221
|
XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]);
|
1078
|
-
/*!< The 8 accumulators.
|
1222
|
+
/*!< The 8 accumulators. See @ref XXH32_state_s::v and @ref XXH64_state_s::v */
|
1079
1223
|
XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]);
|
1080
1224
|
/*!< Used to store a custom secret generated from a seed. */
|
1081
1225
|
XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]);
|
@@ -1118,66 +1262,111 @@ struct XXH3_state_s {
|
|
1118
1262
|
#define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; }
|
1119
1263
|
|
1120
1264
|
|
1121
|
-
|
1265
|
+
/*!
|
1122
1266
|
* simple alias to pre-selected XXH3_128bits variant
|
1123
1267
|
*/
|
1124
|
-
XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
|
1268
|
+
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
|
1125
1269
|
|
1126
1270
|
|
1127
1271
|
/* === Experimental API === */
|
1128
1272
|
/* Symbols defined below must be considered tied to a specific library version. */
|
1129
1273
|
|
1130
|
-
|
1274
|
+
/*!
|
1131
1275
|
* XXH3_generateSecret():
|
1132
1276
|
*
|
1133
1277
|
* Derive a high-entropy secret from any user-defined content, named customSeed.
|
1134
1278
|
* 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
|
1279
|
+
* The `_withSecret()` variants are useful to provide a higher level of protection
|
1280
|
+
* than 64-bit seed, as it becomes much more difficult for an external actor to
|
1281
|
+
* guess how to impact the calculation logic.
|
1137
1282
|
*
|
1138
1283
|
* 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
|
1284
|
+
* and derives from it a high-entropy secret of length @p secretSize into an
|
1285
|
+
* already allocated buffer @p secretBuffer.
|
1142
1286
|
*
|
1143
1287
|
* The generated secret can then be used with any `*_withSecret()` variant.
|
1144
|
-
*
|
1145
|
-
*
|
1288
|
+
* The functions @ref XXH3_128bits_withSecret(), @ref XXH3_64bits_withSecret(),
|
1289
|
+
* @ref XXH3_128bits_reset_withSecret() and @ref XXH3_64bits_reset_withSecret()
|
1146
1290
|
* are part of this list. They all accept a `secret` parameter
|
1147
|
-
* which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN)
|
1291
|
+
* which must be large enough for implementation reasons (>= @ref XXH3_SECRET_SIZE_MIN)
|
1148
1292
|
* _and_ feature very high entropy (consist of random-looking bytes).
|
1149
|
-
* These conditions can be a high bar to meet, so
|
1150
|
-
*
|
1293
|
+
* These conditions can be a high bar to meet, so @ref XXH3_generateSecret() can
|
1294
|
+
* be employed to ensure proper quality.
|
1295
|
+
*
|
1296
|
+
* @p customSeed can be anything. It can have any size, even small ones,
|
1297
|
+
* and its content can be anything, even "poor entropy" sources such as a bunch
|
1298
|
+
* of zeroes. The resulting `secret` will nonetheless provide all required qualities.
|
1151
1299
|
*
|
1152
|
-
*
|
1153
|
-
*
|
1154
|
-
*
|
1300
|
+
* @pre
|
1301
|
+
* - @p secretSize must be >= @ref XXH3_SECRET_SIZE_MIN
|
1302
|
+
* - When @p customSeedSize > 0, supplying NULL as customSeed is undefined behavior.
|
1155
1303
|
*
|
1156
|
-
*
|
1304
|
+
* Example code:
|
1305
|
+
* @code{.c}
|
1306
|
+
* #include <stdio.h>
|
1307
|
+
* #include <stdlib.h>
|
1308
|
+
* #include <string.h>
|
1309
|
+
* #define XXH_STATIC_LINKING_ONLY // expose unstable API
|
1310
|
+
* #include "xxhash.h"
|
1311
|
+
* // Hashes argv[2] using the entropy from argv[1].
|
1312
|
+
* int main(int argc, char* argv[])
|
1313
|
+
* {
|
1314
|
+
* char secret[XXH3_SECRET_SIZE_MIN];
|
1315
|
+
* if (argv != 3) { return 1; }
|
1316
|
+
* XXH3_generateSecret(secret, sizeof(secret), argv[1], strlen(argv[1]));
|
1317
|
+
* XXH64_hash_t h = XXH3_64bits_withSecret(
|
1318
|
+
* argv[2], strlen(argv[2]),
|
1319
|
+
* secret, sizeof(secret)
|
1320
|
+
* );
|
1321
|
+
* printf("%016llx\n", (unsigned long long) h);
|
1322
|
+
* }
|
1323
|
+
* @endcode
|
1157
1324
|
*/
|
1158
1325
|
XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize);
|
1159
1326
|
|
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.
|
1327
|
+
/*!
|
1328
|
+
* @brief Generate the same secret as the _withSeed() variants.
|
1168
1329
|
*
|
1169
1330
|
* The generated secret can be used in combination with
|
1170
1331
|
*`*_withSecret()` and `_withSecretandSeed()` variants.
|
1171
|
-
*
|
1172
|
-
*
|
1332
|
+
*
|
1333
|
+
* Example C++ `std::string` hash class:
|
1334
|
+
* @code{.cpp}
|
1335
|
+
* #include <string>
|
1336
|
+
* #define XXH_STATIC_LINKING_ONLY // expose unstable API
|
1337
|
+
* #include "xxhash.h"
|
1338
|
+
* // Slow, seeds each time
|
1339
|
+
* class HashSlow {
|
1340
|
+
* XXH64_hash_t seed;
|
1341
|
+
* public:
|
1342
|
+
* HashSlow(XXH64_hash_t s) : seed{s} {}
|
1343
|
+
* size_t operator()(const std::string& x) const {
|
1344
|
+
* return size_t{XXH3_64bits_withSeed(x.c_str(), x.length(), seed)};
|
1345
|
+
* }
|
1346
|
+
* };
|
1347
|
+
* // Fast, caches the seeded secret for future uses.
|
1348
|
+
* class HashFast {
|
1349
|
+
* unsigned char secret[XXH3_SECRET_SIZE_MIN];
|
1350
|
+
* public:
|
1351
|
+
* HashFast(XXH64_hash_t s) {
|
1352
|
+
* XXH3_generateSecret_fromSeed(secret, seed);
|
1353
|
+
* }
|
1354
|
+
* size_t operator()(const std::string& x) const {
|
1355
|
+
* return size_t{
|
1356
|
+
* XXH3_64bits_withSecret(x.c_str(), x.length(), secret, sizeof(secret))
|
1357
|
+
* };
|
1358
|
+
* }
|
1359
|
+
* };
|
1360
|
+
* @endcode
|
1361
|
+
* @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes
|
1362
|
+
* @param seed The seed to seed the state.
|
1173
1363
|
*/
|
1174
1364
|
XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed);
|
1175
1365
|
|
1176
|
-
|
1177
|
-
* *_withSecretandSeed() :
|
1366
|
+
/*!
|
1178
1367
|
* 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).
|
1368
|
+
* @p seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes)
|
1369
|
+
* or @p secret for "large" keys (>= XXH3_MIDSIZE_MAX).
|
1181
1370
|
*
|
1182
1371
|
* This generally benefits speed, compared to `_withSeed()` or `_withSecret()`.
|
1183
1372
|
* `_withSeed()` has to generate the secret on the fly for "large" keys.
|
@@ -1186,7 +1375,7 @@ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_
|
|
1186
1375
|
* which requires more instructions than _withSeed() variants.
|
1187
1376
|
* Therefore, _withSecretandSeed variant combines the best of both worlds.
|
1188
1377
|
*
|
1189
|
-
* When @secret has been generated by XXH3_generateSecret_fromSeed(),
|
1378
|
+
* When @p secret has been generated by XXH3_generateSecret_fromSeed(),
|
1190
1379
|
* this variant produces *exactly* the same results as `_withSeed()` variant,
|
1191
1380
|
* hence offering only a pure speed benefit on "large" input,
|
1192
1381
|
* by skipping the need to regenerate the secret for every large input.
|
@@ -1195,26 +1384,26 @@ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_
|
|
1195
1384
|
* for example with XXH3_64bits(), which then becomes the seed,
|
1196
1385
|
* and then employ both the seed and the secret in _withSecretandSeed().
|
1197
1386
|
* 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
|
-
*
|
1387
|
+
* has a 50% chance to swap each bit in the output, via its impact to the seed.
|
1388
|
+
*
|
1200
1389
|
* This is not guaranteed when using the secret directly in "small data" scenarios,
|
1201
1390
|
* because only portions of the secret are employed for small data.
|
1202
1391
|
*/
|
1203
|
-
XXH_PUBLIC_API XXH64_hash_t
|
1392
|
+
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t
|
1204
1393
|
XXH3_64bits_withSecretandSeed(const void* data, size_t len,
|
1205
1394
|
const void* secret, size_t secretSize,
|
1206
1395
|
XXH64_hash_t seed);
|
1207
|
-
|
1208
|
-
XXH_PUBLIC_API XXH128_hash_t
|
1209
|
-
XXH3_128bits_withSecretandSeed(const void*
|
1396
|
+
/*! @copydoc XXH3_64bits_withSecretandSeed() */
|
1397
|
+
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t
|
1398
|
+
XXH3_128bits_withSecretandSeed(const void* input, size_t length,
|
1210
1399
|
const void* secret, size_t secretSize,
|
1211
1400
|
XXH64_hash_t seed64);
|
1212
|
-
|
1401
|
+
/*! @copydoc XXH3_64bits_withSecretandSeed() */
|
1213
1402
|
XXH_PUBLIC_API XXH_errorcode
|
1214
1403
|
XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
|
1215
1404
|
const void* secret, size_t secretSize,
|
1216
1405
|
XXH64_hash_t seed64);
|
1217
|
-
|
1406
|
+
/*! @copydoc XXH3_64bits_withSecretandSeed() */
|
1218
1407
|
XXH_PUBLIC_API XXH_errorcode
|
1219
1408
|
XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
|
1220
1409
|
const void* secret, size_t secretSize,
|
@@ -1275,7 +1464,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
|
|
1275
1464
|
/*!
|
1276
1465
|
* @brief Define this to disable 64-bit code.
|
1277
1466
|
*
|
1278
|
-
* Useful if only using the @ref
|
1467
|
+
* Useful if only using the @ref XXH32_family and you have a strict C90 compiler.
|
1279
1468
|
*/
|
1280
1469
|
# define XXH_NO_LONG_LONG
|
1281
1470
|
# undef XXH_NO_LONG_LONG /* don't actually */
|
@@ -1449,6 +1638,22 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
|
|
1449
1638
|
/* *************************************
|
1450
1639
|
* Includes & Memory related functions
|
1451
1640
|
***************************************/
|
1641
|
+
#if defined(XXH_NO_STDLIB)
|
1642
|
+
|
1643
|
+
/* When requesting to disable any mention of stdlib,
|
1644
|
+
* the library loses the ability to invoked malloc / free.
|
1645
|
+
* In practice, it means that functions like `XXH*_createState()`
|
1646
|
+
* will always fail, and return NULL.
|
1647
|
+
* This flag is useful in situations where
|
1648
|
+
* xxhash.h is integrated into some kernel, embedded or limited environment
|
1649
|
+
* without access to dynamic allocation.
|
1650
|
+
*/
|
1651
|
+
|
1652
|
+
static XXH_CONSTF void* XXH_malloc(size_t s) { (void)s; return NULL; }
|
1653
|
+
static void XXH_free(void* p) { (void)p; }
|
1654
|
+
|
1655
|
+
#else
|
1656
|
+
|
1452
1657
|
/*
|
1453
1658
|
* Modify the local functions below should you wish to use
|
1454
1659
|
* different memory routines for malloc() and free()
|
@@ -1459,13 +1664,15 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
|
|
1459
1664
|
* @internal
|
1460
1665
|
* @brief Modify this function to use a different routine than malloc().
|
1461
1666
|
*/
|
1462
|
-
static void* XXH_malloc(size_t s) { return
|
1667
|
+
static XXH_MALLOCF void* XXH_malloc(size_t s) { return malloc(s); }
|
1463
1668
|
|
1464
1669
|
/*!
|
1465
1670
|
* @internal
|
1466
1671
|
* @brief Modify this function to use a different routine than free().
|
1467
1672
|
*/
|
1468
|
-
static void XXH_free(void* p) {
|
1673
|
+
static void XXH_free(void* p) { free(p); }
|
1674
|
+
|
1675
|
+
#endif /* XXH_NO_STDLIB */
|
1469
1676
|
|
1470
1677
|
#include <string.h>
|
1471
1678
|
|
@@ -1542,8 +1749,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
|
|
1542
1749
|
/* note: use after variable declarations */
|
1543
1750
|
#ifndef XXH_STATIC_ASSERT
|
1544
1751
|
# 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)
|
1752
|
+
# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { _Static_assert((c),m); } while(0)
|
1547
1753
|
# elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */
|
1548
1754
|
# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
|
1549
1755
|
# else
|
@@ -1878,8 +2084,10 @@ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
|
|
1878
2084
|
*********************************************************************/
|
1879
2085
|
/*!
|
1880
2086
|
* @}
|
1881
|
-
* @defgroup
|
2087
|
+
* @defgroup XXH32_impl XXH32 implementation
|
1882
2088
|
* @ingroup impl
|
2089
|
+
*
|
2090
|
+
* Details on the XXH32 implementation.
|
1883
2091
|
* @{
|
1884
2092
|
*/
|
1885
2093
|
/* #define instead of static const, to be used as initializers */
|
@@ -1959,17 +2167,17 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
|
|
1959
2167
|
* The final mix ensures that all input bits have a chance to impact any bit in
|
1960
2168
|
* the output digest, resulting in an unbiased distribution.
|
1961
2169
|
*
|
1962
|
-
* @param
|
2170
|
+
* @param hash The hash to avalanche.
|
1963
2171
|
* @return The avalanched hash.
|
1964
2172
|
*/
|
1965
|
-
static xxh_u32 XXH32_avalanche(xxh_u32
|
2173
|
+
static xxh_u32 XXH32_avalanche(xxh_u32 hash)
|
1966
2174
|
{
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
return
|
2175
|
+
hash ^= hash >> 15;
|
2176
|
+
hash *= XXH_PRIME32_2;
|
2177
|
+
hash ^= hash >> 13;
|
2178
|
+
hash *= XXH_PRIME32_3;
|
2179
|
+
hash ^= hash >> 16;
|
2180
|
+
return hash;
|
1973
2181
|
}
|
1974
2182
|
|
1975
2183
|
#define XXH_get32bits(p) XXH_readLE32_align(p, align)
|
@@ -1982,24 +2190,25 @@ static xxh_u32 XXH32_avalanche(xxh_u32 h32)
|
|
1982
2190
|
* This final stage will digest them to ensure that all input bytes are present
|
1983
2191
|
* in the final mix.
|
1984
2192
|
*
|
1985
|
-
* @param
|
2193
|
+
* @param hash The hash to finalize.
|
1986
2194
|
* @param ptr The pointer to the remaining input.
|
1987
2195
|
* @param len The remaining length, modulo 16.
|
1988
2196
|
* @param align Whether @p ptr is aligned.
|
1989
2197
|
* @return The finalized hash.
|
2198
|
+
* @see XXH64_finalize().
|
1990
2199
|
*/
|
1991
|
-
static xxh_u32
|
1992
|
-
XXH32_finalize(xxh_u32
|
2200
|
+
static XXH_PUREF xxh_u32
|
2201
|
+
XXH32_finalize(xxh_u32 hash, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
1993
2202
|
{
|
1994
|
-
#define XXH_PROCESS1 do {
|
1995
|
-
|
1996
|
-
|
2203
|
+
#define XXH_PROCESS1 do { \
|
2204
|
+
hash += (*ptr++) * XXH_PRIME32_5; \
|
2205
|
+
hash = XXH_rotl32(hash, 11) * XXH_PRIME32_1; \
|
1997
2206
|
} while (0)
|
1998
2207
|
|
1999
|
-
#define XXH_PROCESS4 do {
|
2000
|
-
|
2001
|
-
ptr += 4;
|
2002
|
-
|
2208
|
+
#define XXH_PROCESS4 do { \
|
2209
|
+
hash += XXH_get32bits(ptr) * XXH_PRIME32_3; \
|
2210
|
+
ptr += 4; \
|
2211
|
+
hash = XXH_rotl32(hash, 17) * XXH_PRIME32_4; \
|
2003
2212
|
} while (0)
|
2004
2213
|
|
2005
2214
|
if (ptr==NULL) XXH_ASSERT(len == 0);
|
@@ -2015,7 +2224,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
|
2015
2224
|
XXH_PROCESS1;
|
2016
2225
|
--len;
|
2017
2226
|
}
|
2018
|
-
return XXH32_avalanche(
|
2227
|
+
return XXH32_avalanche(hash);
|
2019
2228
|
} else {
|
2020
2229
|
switch(len&15) /* or switch(bEnd - p) */ {
|
2021
2230
|
case 12: XXH_PROCESS4;
|
@@ -2023,7 +2232,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
|
2023
2232
|
case 8: XXH_PROCESS4;
|
2024
2233
|
XXH_FALLTHROUGH;
|
2025
2234
|
case 4: XXH_PROCESS4;
|
2026
|
-
return XXH32_avalanche(
|
2235
|
+
return XXH32_avalanche(hash);
|
2027
2236
|
|
2028
2237
|
case 13: XXH_PROCESS4;
|
2029
2238
|
XXH_FALLTHROUGH;
|
@@ -2031,7 +2240,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
|
2031
2240
|
XXH_FALLTHROUGH;
|
2032
2241
|
case 5: XXH_PROCESS4;
|
2033
2242
|
XXH_PROCESS1;
|
2034
|
-
return XXH32_avalanche(
|
2243
|
+
return XXH32_avalanche(hash);
|
2035
2244
|
|
2036
2245
|
case 14: XXH_PROCESS4;
|
2037
2246
|
XXH_FALLTHROUGH;
|
@@ -2040,7 +2249,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
|
2040
2249
|
case 6: XXH_PROCESS4;
|
2041
2250
|
XXH_PROCESS1;
|
2042
2251
|
XXH_PROCESS1;
|
2043
|
-
return XXH32_avalanche(
|
2252
|
+
return XXH32_avalanche(hash);
|
2044
2253
|
|
2045
2254
|
case 15: XXH_PROCESS4;
|
2046
2255
|
XXH_FALLTHROUGH;
|
@@ -2054,10 +2263,10 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
|
2054
2263
|
XXH_FALLTHROUGH;
|
2055
2264
|
case 1: XXH_PROCESS1;
|
2056
2265
|
XXH_FALLTHROUGH;
|
2057
|
-
case 0: return XXH32_avalanche(
|
2266
|
+
case 0: return XXH32_avalanche(hash);
|
2058
2267
|
}
|
2059
2268
|
XXH_ASSERT(0);
|
2060
|
-
return
|
2269
|
+
return hash; /* reaching this point is deemed impossible */
|
2061
2270
|
}
|
2062
2271
|
}
|
2063
2272
|
|
@@ -2077,7 +2286,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
|
2077
2286
|
* @param align Whether @p input is aligned.
|
2078
2287
|
* @return The calculated hash.
|
2079
2288
|
*/
|
2080
|
-
XXH_FORCE_INLINE xxh_u32
|
2289
|
+
XXH_FORCE_INLINE XXH_PUREF xxh_u32
|
2081
2290
|
XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align)
|
2082
2291
|
{
|
2083
2292
|
xxh_u32 h32;
|
@@ -2110,7 +2319,7 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment
|
|
2110
2319
|
return XXH32_finalize(h32, input, len&15, align);
|
2111
2320
|
}
|
2112
2321
|
|
2113
|
-
/*! @ingroup
|
2322
|
+
/*! @ingroup XXH32_family */
|
2114
2323
|
XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed)
|
2115
2324
|
{
|
2116
2325
|
#if 0
|
@@ -2132,27 +2341,25 @@ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t s
|
|
2132
2341
|
|
2133
2342
|
|
2134
2343
|
/******* Hash streaming *******/
|
2135
|
-
/*!
|
2136
|
-
* @ingroup xxh32_family
|
2137
|
-
*/
|
2344
|
+
/*! @ingroup XXH32_family */
|
2138
2345
|
XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
|
2139
2346
|
{
|
2140
2347
|
return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
|
2141
2348
|
}
|
2142
|
-
/*! @ingroup
|
2349
|
+
/*! @ingroup XXH32_family */
|
2143
2350
|
XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
|
2144
2351
|
{
|
2145
2352
|
XXH_free(statePtr);
|
2146
2353
|
return XXH_OK;
|
2147
2354
|
}
|
2148
2355
|
|
2149
|
-
/*! @ingroup
|
2356
|
+
/*! @ingroup XXH32_family */
|
2150
2357
|
XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
|
2151
2358
|
{
|
2152
2359
|
XXH_memcpy(dstState, srcState, sizeof(*dstState));
|
2153
2360
|
}
|
2154
2361
|
|
2155
|
-
/*! @ingroup
|
2362
|
+
/*! @ingroup XXH32_family */
|
2156
2363
|
XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed)
|
2157
2364
|
{
|
2158
2365
|
XXH_ASSERT(statePtr != NULL);
|
@@ -2165,7 +2372,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s
|
|
2165
2372
|
}
|
2166
2373
|
|
2167
2374
|
|
2168
|
-
/*! @ingroup
|
2375
|
+
/*! @ingroup XXH32_family */
|
2169
2376
|
XXH_PUBLIC_API XXH_errorcode
|
2170
2377
|
XXH32_update(XXH32_state_t* state, const void* input, size_t len)
|
2171
2378
|
{
|
@@ -2220,7 +2427,7 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len)
|
|
2220
2427
|
}
|
2221
2428
|
|
2222
2429
|
|
2223
|
-
/*! @ingroup
|
2430
|
+
/*! @ingroup XXH32_family */
|
2224
2431
|
XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
|
2225
2432
|
{
|
2226
2433
|
xxh_u32 h32;
|
@@ -2243,7 +2450,7 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
|
|
2243
2450
|
/******* Canonical representation *******/
|
2244
2451
|
|
2245
2452
|
/*!
|
2246
|
-
* @ingroup
|
2453
|
+
* @ingroup XXH32_family
|
2247
2454
|
* The default return values from XXH functions are unsigned 32 and 64 bit
|
2248
2455
|
* integers.
|
2249
2456
|
*
|
@@ -2262,7 +2469,7 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t
|
|
2262
2469
|
if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
|
2263
2470
|
XXH_memcpy(dst, &hash, sizeof(*dst));
|
2264
2471
|
}
|
2265
|
-
/*! @ingroup
|
2472
|
+
/*! @ingroup XXH32_family */
|
2266
2473
|
XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
|
2267
2474
|
{
|
2268
2475
|
return XXH_readBE32(src);
|
@@ -2406,8 +2613,10 @@ XXH_readLE64_align(const void* ptr, XXH_alignment align)
|
|
2406
2613
|
/******* xxh64 *******/
|
2407
2614
|
/*!
|
2408
2615
|
* @}
|
2409
|
-
* @defgroup
|
2616
|
+
* @defgroup XXH64_impl XXH64 implementation
|
2410
2617
|
* @ingroup impl
|
2618
|
+
*
|
2619
|
+
* Details on the XXH64 implementation.
|
2411
2620
|
* @{
|
2412
2621
|
*/
|
2413
2622
|
/* #define rather that static const, to be used as initializers */
|
@@ -2425,6 +2634,7 @@ XXH_readLE64_align(const void* ptr, XXH_alignment align)
|
|
2425
2634
|
# define PRIME64_5 XXH_PRIME64_5
|
2426
2635
|
#endif
|
2427
2636
|
|
2637
|
+
/*! @copydoc XXH32_round */
|
2428
2638
|
static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input)
|
2429
2639
|
{
|
2430
2640
|
acc += input * XXH_PRIME64_2;
|
@@ -2441,43 +2651,59 @@ static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val)
|
|
2441
2651
|
return acc;
|
2442
2652
|
}
|
2443
2653
|
|
2444
|
-
|
2654
|
+
/*! @copydoc XXH32_avalanche */
|
2655
|
+
static xxh_u64 XXH64_avalanche(xxh_u64 hash)
|
2445
2656
|
{
|
2446
|
-
|
2447
|
-
|
2448
|
-
|
2449
|
-
|
2450
|
-
|
2451
|
-
return
|
2657
|
+
hash ^= hash >> 33;
|
2658
|
+
hash *= XXH_PRIME64_2;
|
2659
|
+
hash ^= hash >> 29;
|
2660
|
+
hash *= XXH_PRIME64_3;
|
2661
|
+
hash ^= hash >> 32;
|
2662
|
+
return hash;
|
2452
2663
|
}
|
2453
2664
|
|
2454
2665
|
|
2455
2666
|
#define XXH_get64bits(p) XXH_readLE64_align(p, align)
|
2456
2667
|
|
2457
|
-
|
2458
|
-
|
2668
|
+
/*!
|
2669
|
+
* @internal
|
2670
|
+
* @brief Processes the last 0-31 bytes of @p ptr.
|
2671
|
+
*
|
2672
|
+
* There may be up to 31 bytes remaining to consume from the input.
|
2673
|
+
* This final stage will digest them to ensure that all input bytes are present
|
2674
|
+
* in the final mix.
|
2675
|
+
*
|
2676
|
+
* @param hash The hash to finalize.
|
2677
|
+
* @param ptr The pointer to the remaining input.
|
2678
|
+
* @param len The remaining length, modulo 32.
|
2679
|
+
* @param align Whether @p ptr is aligned.
|
2680
|
+
* @return The finalized hash
|
2681
|
+
* @see XXH32_finalize().
|
2682
|
+
*/
|
2683
|
+
static XXH_PUREF xxh_u64
|
2684
|
+
XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
2459
2685
|
{
|
2460
2686
|
if (ptr==NULL) XXH_ASSERT(len == 0);
|
2461
2687
|
len &= 31;
|
2462
2688
|
while (len >= 8) {
|
2463
2689
|
xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr));
|
2464
2690
|
ptr += 8;
|
2465
|
-
|
2466
|
-
|
2691
|
+
hash ^= k1;
|
2692
|
+
hash = XXH_rotl64(hash,27) * XXH_PRIME64_1 + XXH_PRIME64_4;
|
2467
2693
|
len -= 8;
|
2468
2694
|
}
|
2469
2695
|
if (len >= 4) {
|
2470
|
-
|
2696
|
+
hash ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1;
|
2471
2697
|
ptr += 4;
|
2472
|
-
|
2698
|
+
hash = XXH_rotl64(hash, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
|
2473
2699
|
len -= 4;
|
2474
2700
|
}
|
2475
2701
|
while (len > 0) {
|
2476
|
-
|
2477
|
-
|
2702
|
+
hash ^= (*ptr++) * XXH_PRIME64_5;
|
2703
|
+
hash = XXH_rotl64(hash, 11) * XXH_PRIME64_1;
|
2478
2704
|
--len;
|
2479
2705
|
}
|
2480
|
-
return XXH64_avalanche(
|
2706
|
+
return XXH64_avalanche(hash);
|
2481
2707
|
}
|
2482
2708
|
|
2483
2709
|
#ifdef XXH_OLD_NAMES
|
@@ -2490,7 +2716,15 @@ XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align)
|
|
2490
2716
|
# undef XXH_PROCESS8_64
|
2491
2717
|
#endif
|
2492
2718
|
|
2493
|
-
|
2719
|
+
/*!
|
2720
|
+
* @internal
|
2721
|
+
* @brief The implementation for @ref XXH64().
|
2722
|
+
*
|
2723
|
+
* @param input , len , seed Directly passed from @ref XXH64().
|
2724
|
+
* @param align Whether @p input is aligned.
|
2725
|
+
* @return The calculated hash.
|
2726
|
+
*/
|
2727
|
+
XXH_FORCE_INLINE XXH_PUREF xxh_u64
|
2494
2728
|
XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align)
|
2495
2729
|
{
|
2496
2730
|
xxh_u64 h64;
|
@@ -2527,7 +2761,7 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment
|
|
2527
2761
|
}
|
2528
2762
|
|
2529
2763
|
|
2530
|
-
/*! @ingroup
|
2764
|
+
/*! @ingroup XXH64_family */
|
2531
2765
|
XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed)
|
2532
2766
|
{
|
2533
2767
|
#if 0
|
@@ -2549,25 +2783,25 @@ XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t s
|
|
2549
2783
|
|
2550
2784
|
/******* Hash Streaming *******/
|
2551
2785
|
|
2552
|
-
/*! @ingroup
|
2786
|
+
/*! @ingroup XXH64_family*/
|
2553
2787
|
XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
|
2554
2788
|
{
|
2555
2789
|
return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
|
2556
2790
|
}
|
2557
|
-
/*! @ingroup
|
2791
|
+
/*! @ingroup XXH64_family */
|
2558
2792
|
XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
|
2559
2793
|
{
|
2560
2794
|
XXH_free(statePtr);
|
2561
2795
|
return XXH_OK;
|
2562
2796
|
}
|
2563
2797
|
|
2564
|
-
/*! @ingroup
|
2798
|
+
/*! @ingroup XXH64_family */
|
2565
2799
|
XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
|
2566
2800
|
{
|
2567
2801
|
XXH_memcpy(dstState, srcState, sizeof(*dstState));
|
2568
2802
|
}
|
2569
2803
|
|
2570
|
-
/*! @ingroup
|
2804
|
+
/*! @ingroup XXH64_family */
|
2571
2805
|
XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed)
|
2572
2806
|
{
|
2573
2807
|
XXH_ASSERT(statePtr != NULL);
|
@@ -2579,7 +2813,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t s
|
|
2579
2813
|
return XXH_OK;
|
2580
2814
|
}
|
2581
2815
|
|
2582
|
-
/*! @ingroup
|
2816
|
+
/*! @ingroup XXH64_family */
|
2583
2817
|
XXH_PUBLIC_API XXH_errorcode
|
2584
2818
|
XXH64_update (XXH64_state_t* state, const void* input, size_t len)
|
2585
2819
|
{
|
@@ -2631,7 +2865,7 @@ XXH64_update (XXH64_state_t* state, const void* input, size_t len)
|
|
2631
2865
|
}
|
2632
2866
|
|
2633
2867
|
|
2634
|
-
/*! @ingroup
|
2868
|
+
/*! @ingroup XXH64_family */
|
2635
2869
|
XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state)
|
2636
2870
|
{
|
2637
2871
|
xxh_u64 h64;
|
@@ -2654,7 +2888,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state)
|
|
2654
2888
|
|
2655
2889
|
/******* Canonical representation *******/
|
2656
2890
|
|
2657
|
-
/*! @ingroup
|
2891
|
+
/*! @ingroup XXH64_family */
|
2658
2892
|
XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
|
2659
2893
|
{
|
2660
2894
|
XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
|
@@ -2662,7 +2896,7 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t
|
|
2662
2896
|
XXH_memcpy(dst, &hash, sizeof(*dst));
|
2663
2897
|
}
|
2664
2898
|
|
2665
|
-
/*! @ingroup
|
2899
|
+
/*! @ingroup XXH64_family */
|
2666
2900
|
XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
|
2667
2901
|
{
|
2668
2902
|
return XXH_readBE64(src);
|
@@ -2676,7 +2910,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src
|
|
2676
2910
|
************************************************************************ */
|
2677
2911
|
/*!
|
2678
2912
|
* @}
|
2679
|
-
* @defgroup
|
2913
|
+
* @defgroup XXH3_impl XXH3 implementation
|
2680
2914
|
* @ingroup impl
|
2681
2915
|
* @{
|
2682
2916
|
*/
|
@@ -3444,7 +3678,7 @@ XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs)
|
|
3444
3678
|
}
|
3445
3679
|
|
3446
3680
|
/*! Seems to produce slightly better code on GCC for some reason. */
|
3447
|
-
XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
|
3681
|
+
XXH_FORCE_INLINE XXH_CONSTF xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
|
3448
3682
|
{
|
3449
3683
|
XXH_ASSERT(0 <= shift && shift < 64);
|
3450
3684
|
return v64 ^ (v64 >> shift);
|
@@ -3511,7 +3745,7 @@ static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len)
|
|
3511
3745
|
*
|
3512
3746
|
* This adds an extra layer of strength for custom secrets.
|
3513
3747
|
*/
|
3514
|
-
XXH_FORCE_INLINE XXH64_hash_t
|
3748
|
+
XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
|
3515
3749
|
XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
|
3516
3750
|
{
|
3517
3751
|
XXH_ASSERT(input != NULL);
|
@@ -3533,7 +3767,7 @@ XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_h
|
|
3533
3767
|
}
|
3534
3768
|
}
|
3535
3769
|
|
3536
|
-
XXH_FORCE_INLINE XXH64_hash_t
|
3770
|
+
XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
|
3537
3771
|
XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
|
3538
3772
|
{
|
3539
3773
|
XXH_ASSERT(input != NULL);
|
@@ -3549,7 +3783,7 @@ XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_h
|
|
3549
3783
|
}
|
3550
3784
|
}
|
3551
3785
|
|
3552
|
-
XXH_FORCE_INLINE XXH64_hash_t
|
3786
|
+
XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
|
3553
3787
|
XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
|
3554
3788
|
{
|
3555
3789
|
XXH_ASSERT(input != NULL);
|
@@ -3566,7 +3800,7 @@ XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_
|
|
3566
3800
|
}
|
3567
3801
|
}
|
3568
3802
|
|
3569
|
-
XXH_FORCE_INLINE XXH64_hash_t
|
3803
|
+
XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
|
3570
3804
|
XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
|
3571
3805
|
{
|
3572
3806
|
XXH_ASSERT(len <= 16);
|
@@ -3636,7 +3870,7 @@ XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input,
|
|
3636
3870
|
}
|
3637
3871
|
|
3638
3872
|
/* For mid range keys, XXH3 uses a Mum-hash variant. */
|
3639
|
-
XXH_FORCE_INLINE XXH64_hash_t
|
3873
|
+
XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t
|
3640
3874
|
XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
|
3641
3875
|
const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
|
3642
3876
|
XXH64_hash_t seed)
|
@@ -3666,7 +3900,7 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
|
|
3666
3900
|
|
3667
3901
|
#define XXH3_MIDSIZE_MAX 240
|
3668
3902
|
|
3669
|
-
XXH_NO_INLINE XXH64_hash_t
|
3903
|
+
XXH_NO_INLINE XXH_PUREF XXH64_hash_t
|
3670
3904
|
XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
|
3671
3905
|
const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
|
3672
3906
|
XXH64_hash_t seed)
|
@@ -4635,7 +4869,7 @@ XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len,
|
|
4635
4869
|
* Note that inside this no_inline function, we do inline the internal loop,
|
4636
4870
|
* and provide a statically defined secret size to allow optimization of vector loop.
|
4637
4871
|
*/
|
4638
|
-
XXH_NO_INLINE XXH64_hash_t
|
4872
|
+
XXH_NO_INLINE XXH_PUREF XXH64_hash_t
|
4639
4873
|
XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len,
|
4640
4874
|
XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
|
4641
4875
|
{
|
@@ -4713,32 +4947,32 @@ XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len,
|
|
4713
4947
|
|
4714
4948
|
/* === Public entry point === */
|
4715
4949
|
|
4716
|
-
/*! @ingroup
|
4717
|
-
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t
|
4950
|
+
/*! @ingroup XXH3_family */
|
4951
|
+
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t length)
|
4718
4952
|
{
|
4719
|
-
return XXH3_64bits_internal(input,
|
4953
|
+
return XXH3_64bits_internal(input, length, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default);
|
4720
4954
|
}
|
4721
4955
|
|
4722
|
-
/*! @ingroup
|
4956
|
+
/*! @ingroup XXH3_family */
|
4723
4957
|
XXH_PUBLIC_API XXH64_hash_t
|
4724
|
-
XXH3_64bits_withSecret(const void* input, size_t
|
4958
|
+
XXH3_64bits_withSecret(const void* input, size_t length, const void* secret, size_t secretSize)
|
4725
4959
|
{
|
4726
|
-
return XXH3_64bits_internal(input,
|
4960
|
+
return XXH3_64bits_internal(input, length, 0, secret, secretSize, XXH3_hashLong_64b_withSecret);
|
4727
4961
|
}
|
4728
4962
|
|
4729
|
-
/*! @ingroup
|
4963
|
+
/*! @ingroup XXH3_family */
|
4730
4964
|
XXH_PUBLIC_API XXH64_hash_t
|
4731
|
-
XXH3_64bits_withSeed(const void* input, size_t
|
4965
|
+
XXH3_64bits_withSeed(const void* input, size_t length, XXH64_hash_t seed)
|
4732
4966
|
{
|
4733
|
-
return XXH3_64bits_internal(input,
|
4967
|
+
return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed);
|
4734
4968
|
}
|
4735
4969
|
|
4736
4970
|
XXH_PUBLIC_API XXH64_hash_t
|
4737
|
-
XXH3_64bits_withSecretandSeed(const void* input, size_t
|
4971
|
+
XXH3_64bits_withSecretandSeed(const void* input, size_t length, const void* secret, size_t secretSize, XXH64_hash_t seed)
|
4738
4972
|
{
|
4739
|
-
if (
|
4740
|
-
return XXH3_64bits_internal(input,
|
4741
|
-
return XXH3_hashLong_64b_withSecret(input,
|
4973
|
+
if (length <= XXH3_MIDSIZE_MAX)
|
4974
|
+
return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
|
4975
|
+
return XXH3_hashLong_64b_withSecret(input, length, seed, (const xxh_u8*)secret, secretSize);
|
4742
4976
|
}
|
4743
4977
|
|
4744
4978
|
|
@@ -4767,7 +5001,7 @@ XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret,
|
|
4767
5001
|
*
|
4768
5002
|
* Align must be a power of 2 and 8 <= align <= 128.
|
4769
5003
|
*/
|
4770
|
-
static void* XXH_alignedMalloc(size_t s, size_t align)
|
5004
|
+
static XXH_MALLOCF void* XXH_alignedMalloc(size_t s, size_t align)
|
4771
5005
|
{
|
4772
5006
|
XXH_ASSERT(align <= 128 && align >= 8); /* range check */
|
4773
5007
|
XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */
|
@@ -4809,7 +5043,7 @@ static void XXH_alignedFree(void* p)
|
|
4809
5043
|
XXH_free(base);
|
4810
5044
|
}
|
4811
5045
|
}
|
4812
|
-
/*! @ingroup
|
5046
|
+
/*! @ingroup XXH3_family */
|
4813
5047
|
XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
|
4814
5048
|
{
|
4815
5049
|
XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64);
|
@@ -4818,14 +5052,14 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
|
|
4818
5052
|
return state;
|
4819
5053
|
}
|
4820
5054
|
|
4821
|
-
/*! @ingroup
|
5055
|
+
/*! @ingroup XXH3_family */
|
4822
5056
|
XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr)
|
4823
5057
|
{
|
4824
5058
|
XXH_alignedFree(statePtr);
|
4825
5059
|
return XXH_OK;
|
4826
5060
|
}
|
4827
5061
|
|
4828
|
-
/*! @ingroup
|
5062
|
+
/*! @ingroup XXH3_family */
|
4829
5063
|
XXH_PUBLIC_API void
|
4830
5064
|
XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state)
|
4831
5065
|
{
|
@@ -4859,7 +5093,7 @@ XXH3_reset_internal(XXH3_state_t* statePtr,
|
|
4859
5093
|
statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE;
|
4860
5094
|
}
|
4861
5095
|
|
4862
|
-
/*! @ingroup
|
5096
|
+
/*! @ingroup XXH3_family */
|
4863
5097
|
XXH_PUBLIC_API XXH_errorcode
|
4864
5098
|
XXH3_64bits_reset(XXH3_state_t* statePtr)
|
4865
5099
|
{
|
@@ -4868,7 +5102,7 @@ XXH3_64bits_reset(XXH3_state_t* statePtr)
|
|
4868
5102
|
return XXH_OK;
|
4869
5103
|
}
|
4870
5104
|
|
4871
|
-
/*! @ingroup
|
5105
|
+
/*! @ingroup XXH3_family */
|
4872
5106
|
XXH_PUBLIC_API XXH_errorcode
|
4873
5107
|
XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
|
4874
5108
|
{
|
@@ -4879,7 +5113,7 @@ XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t
|
|
4879
5113
|
return XXH_OK;
|
4880
5114
|
}
|
4881
5115
|
|
4882
|
-
/*! @ingroup
|
5116
|
+
/*! @ingroup XXH3_family */
|
4883
5117
|
XXH_PUBLIC_API XXH_errorcode
|
4884
5118
|
XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
|
4885
5119
|
{
|
@@ -4891,7 +5125,7 @@ XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
|
|
4891
5125
|
return XXH_OK;
|
4892
5126
|
}
|
4893
5127
|
|
4894
|
-
/*! @ingroup
|
5128
|
+
/*! @ingroup XXH3_family */
|
4895
5129
|
XXH_PUBLIC_API XXH_errorcode
|
4896
5130
|
XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64)
|
4897
5131
|
{
|
@@ -5053,7 +5287,7 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state,
|
|
5053
5287
|
return XXH_OK;
|
5054
5288
|
}
|
5055
5289
|
|
5056
|
-
/*! @ingroup
|
5290
|
+
/*! @ingroup XXH3_family */
|
5057
5291
|
XXH_PUBLIC_API XXH_errorcode
|
5058
5292
|
XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len)
|
5059
5293
|
{
|
@@ -5096,7 +5330,7 @@ XXH3_digest_long (XXH64_hash_t* acc,
|
|
5096
5330
|
}
|
5097
5331
|
}
|
5098
5332
|
|
5099
|
-
/*! @ingroup
|
5333
|
+
/*! @ingroup XXH3_family */
|
5100
5334
|
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
|
5101
5335
|
{
|
5102
5336
|
const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
|
@@ -5133,7 +5367,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
|
|
5133
5367
|
* fast for a _128-bit_ hash on 32-bit (it usually clears XXH64).
|
5134
5368
|
*/
|
5135
5369
|
|
5136
|
-
XXH_FORCE_INLINE XXH128_hash_t
|
5370
|
+
XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
|
5137
5371
|
XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
|
5138
5372
|
{
|
5139
5373
|
/* A doubled version of 1to3_64b with different constants. */
|
@@ -5162,7 +5396,7 @@ XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_
|
|
5162
5396
|
}
|
5163
5397
|
}
|
5164
5398
|
|
5165
|
-
XXH_FORCE_INLINE XXH128_hash_t
|
5399
|
+
XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
|
5166
5400
|
XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
|
5167
5401
|
{
|
5168
5402
|
XXH_ASSERT(input != NULL);
|
@@ -5189,7 +5423,7 @@ XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_
|
|
5189
5423
|
}
|
5190
5424
|
}
|
5191
5425
|
|
5192
|
-
XXH_FORCE_INLINE XXH128_hash_t
|
5426
|
+
XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
|
5193
5427
|
XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
|
5194
5428
|
{
|
5195
5429
|
XXH_ASSERT(input != NULL);
|
@@ -5264,7 +5498,7 @@ XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64
|
|
5264
5498
|
/*
|
5265
5499
|
* Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN
|
5266
5500
|
*/
|
5267
|
-
XXH_FORCE_INLINE XXH128_hash_t
|
5501
|
+
XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
|
5268
5502
|
XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
|
5269
5503
|
{
|
5270
5504
|
XXH_ASSERT(len <= 16);
|
@@ -5295,7 +5529,7 @@ XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2,
|
|
5295
5529
|
}
|
5296
5530
|
|
5297
5531
|
|
5298
|
-
XXH_FORCE_INLINE XXH128_hash_t
|
5532
|
+
XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t
|
5299
5533
|
XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
|
5300
5534
|
const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
|
5301
5535
|
XXH64_hash_t seed)
|
@@ -5328,7 +5562,7 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
|
|
5328
5562
|
}
|
5329
5563
|
}
|
5330
5564
|
|
5331
|
-
XXH_NO_INLINE XXH128_hash_t
|
5565
|
+
XXH_NO_INLINE XXH_PUREF XXH128_hash_t
|
5332
5566
|
XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
|
5333
5567
|
const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
|
5334
5568
|
XXH64_hash_t seed)
|
@@ -5403,9 +5637,9 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len,
|
|
5403
5637
|
}
|
5404
5638
|
|
5405
5639
|
/*
|
5406
|
-
* It's important for performance that XXH3_hashLong is not inlined.
|
5640
|
+
* It's important for performance that XXH3_hashLong() is not inlined.
|
5407
5641
|
*/
|
5408
|
-
XXH_NO_INLINE XXH128_hash_t
|
5642
|
+
XXH_NO_INLINE XXH_PUREF XXH128_hash_t
|
5409
5643
|
XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len,
|
5410
5644
|
XXH64_hash_t seed64,
|
5411
5645
|
const void* XXH_RESTRICT secret, size_t secretLen)
|
@@ -5416,7 +5650,7 @@ XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len,
|
|
5416
5650
|
}
|
5417
5651
|
|
5418
5652
|
/*
|
5419
|
-
* It's important for performance to pass @secretLen (when it's static)
|
5653
|
+
* It's important for performance to pass @p secretLen (when it's static)
|
5420
5654
|
* to the compiler, so that it can properly optimize the vectorized loop.
|
5421
5655
|
*/
|
5422
5656
|
XXH_FORCE_INLINE XXH128_hash_t
|
@@ -5486,7 +5720,7 @@ XXH3_128bits_internal(const void* input, size_t len,
|
|
5486
5720
|
|
5487
5721
|
/* === Public XXH128 API === */
|
5488
5722
|
|
5489
|
-
/*! @ingroup
|
5723
|
+
/*! @ingroup XXH3_family */
|
5490
5724
|
XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len)
|
5491
5725
|
{
|
5492
5726
|
return XXH3_128bits_internal(input, len, 0,
|
@@ -5494,7 +5728,7 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len)
|
|
5494
5728
|
XXH3_hashLong_128b_default);
|
5495
5729
|
}
|
5496
5730
|
|
5497
|
-
/*! @ingroup
|
5731
|
+
/*! @ingroup XXH3_family */
|
5498
5732
|
XXH_PUBLIC_API XXH128_hash_t
|
5499
5733
|
XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
|
5500
5734
|
{
|
@@ -5503,7 +5737,7 @@ XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_
|
|
5503
5737
|
XXH3_hashLong_128b_withSecret);
|
5504
5738
|
}
|
5505
5739
|
|
5506
|
-
/*! @ingroup
|
5740
|
+
/*! @ingroup XXH3_family */
|
5507
5741
|
XXH_PUBLIC_API XXH128_hash_t
|
5508
5742
|
XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
|
5509
5743
|
{
|
@@ -5512,7 +5746,7 @@ XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
|
|
5512
5746
|
XXH3_hashLong_128b_withSeed);
|
5513
5747
|
}
|
5514
5748
|
|
5515
|
-
/*! @ingroup
|
5749
|
+
/*! @ingroup XXH3_family */
|
5516
5750
|
XXH_PUBLIC_API XXH128_hash_t
|
5517
5751
|
XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
|
5518
5752
|
{
|
@@ -5521,7 +5755,7 @@ XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret
|
|
5521
5755
|
return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize);
|
5522
5756
|
}
|
5523
5757
|
|
5524
|
-
/*! @ingroup
|
5758
|
+
/*! @ingroup XXH3_family */
|
5525
5759
|
XXH_PUBLIC_API XXH128_hash_t
|
5526
5760
|
XXH128(const void* input, size_t len, XXH64_hash_t seed)
|
5527
5761
|
{
|
@@ -5536,35 +5770,35 @@ XXH128(const void* input, size_t len, XXH64_hash_t seed)
|
|
5536
5770
|
* The only difference is the finalization routine.
|
5537
5771
|
*/
|
5538
5772
|
|
5539
|
-
/*! @ingroup
|
5773
|
+
/*! @ingroup XXH3_family */
|
5540
5774
|
XXH_PUBLIC_API XXH_errorcode
|
5541
5775
|
XXH3_128bits_reset(XXH3_state_t* statePtr)
|
5542
5776
|
{
|
5543
5777
|
return XXH3_64bits_reset(statePtr);
|
5544
5778
|
}
|
5545
5779
|
|
5546
|
-
/*! @ingroup
|
5780
|
+
/*! @ingroup XXH3_family */
|
5547
5781
|
XXH_PUBLIC_API XXH_errorcode
|
5548
5782
|
XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
|
5549
5783
|
{
|
5550
5784
|
return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize);
|
5551
5785
|
}
|
5552
5786
|
|
5553
|
-
/*! @ingroup
|
5787
|
+
/*! @ingroup XXH3_family */
|
5554
5788
|
XXH_PUBLIC_API XXH_errorcode
|
5555
5789
|
XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
|
5556
5790
|
{
|
5557
5791
|
return XXH3_64bits_reset_withSeed(statePtr, seed);
|
5558
5792
|
}
|
5559
5793
|
|
5560
|
-
/*! @ingroup
|
5794
|
+
/*! @ingroup XXH3_family */
|
5561
5795
|
XXH_PUBLIC_API XXH_errorcode
|
5562
5796
|
XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed)
|
5563
5797
|
{
|
5564
5798
|
return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed);
|
5565
5799
|
}
|
5566
5800
|
|
5567
|
-
/*! @ingroup
|
5801
|
+
/*! @ingroup XXH3_family */
|
5568
5802
|
XXH_PUBLIC_API XXH_errorcode
|
5569
5803
|
XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len)
|
5570
5804
|
{
|
@@ -5572,7 +5806,7 @@ XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len)
|
|
5572
5806
|
XXH3_accumulate_512, XXH3_scrambleAcc);
|
5573
5807
|
}
|
5574
5808
|
|
5575
|
-
/*! @ingroup
|
5809
|
+
/*! @ingroup XXH3_family */
|
5576
5810
|
XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state)
|
5577
5811
|
{
|
5578
5812
|
const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
|
@@ -5603,7 +5837,7 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state)
|
|
5603
5837
|
#include <string.h> /* memcmp, memcpy */
|
5604
5838
|
|
5605
5839
|
/* return : 1 is equal, 0 if different */
|
5606
|
-
/*! @ingroup
|
5840
|
+
/*! @ingroup XXH3_family */
|
5607
5841
|
XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
|
5608
5842
|
{
|
5609
5843
|
/* note : XXH128_hash_t is compact, it has no padding byte */
|
@@ -5611,10 +5845,10 @@ XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
|
|
5611
5845
|
}
|
5612
5846
|
|
5613
5847
|
/* This prototype is compatible with stdlib's qsort().
|
5614
|
-
* return : >0 if *h128_1 > *h128_2
|
5615
|
-
*
|
5616
|
-
*
|
5617
|
-
/*! @ingroup
|
5848
|
+
* @return : >0 if *h128_1 > *h128_2
|
5849
|
+
* <0 if *h128_1 < *h128_2
|
5850
|
+
* =0 if *h128_1 == *h128_2 */
|
5851
|
+
/*! @ingroup XXH3_family */
|
5618
5852
|
XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2)
|
5619
5853
|
{
|
5620
5854
|
XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1;
|
@@ -5627,7 +5861,7 @@ XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2)
|
|
5627
5861
|
|
5628
5862
|
|
5629
5863
|
/*====== Canonical representation ======*/
|
5630
|
-
/*! @ingroup
|
5864
|
+
/*! @ingroup XXH3_family */
|
5631
5865
|
XXH_PUBLIC_API void
|
5632
5866
|
XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash)
|
5633
5867
|
{
|
@@ -5640,7 +5874,7 @@ XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash)
|
|
5640
5874
|
XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64));
|
5641
5875
|
}
|
5642
5876
|
|
5643
|
-
/*! @ingroup
|
5877
|
+
/*! @ingroup XXH3_family */
|
5644
5878
|
XXH_PUBLIC_API XXH128_hash_t
|
5645
5879
|
XXH128_hashFromCanonical(const XXH128_canonical_t* src)
|
5646
5880
|
{
|
@@ -5664,7 +5898,7 @@ XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128)
|
|
5664
5898
|
XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 );
|
5665
5899
|
}
|
5666
5900
|
|
5667
|
-
/*! @ingroup
|
5901
|
+
/*! @ingroup XXH3_family */
|
5668
5902
|
XXH_PUBLIC_API XXH_errorcode
|
5669
5903
|
XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize)
|
5670
5904
|
{
|
@@ -5709,7 +5943,7 @@ XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSee
|
|
5709
5943
|
return XXH_OK;
|
5710
5944
|
}
|
5711
5945
|
|
5712
|
-
/*! @ingroup
|
5946
|
+
/*! @ingroup XXH3_family */
|
5713
5947
|
XXH_PUBLIC_API void
|
5714
5948
|
XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed)
|
5715
5949
|
{
|