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