xxhash 0.2.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,252 +1,308 @@
1
1
  /*
2
- xxHash - Fast Hash algorithm
3
- Copyright (C) 2012-2013, Yann Collet.
4
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
5
-
6
- Redistribution and use in source and binary forms, with or without
7
- modification, are permitted provided that the following conditions are
8
- met:
9
-
10
- * Redistributions of source code must retain the above copyright
11
- notice, this list of conditions and the following disclaimer.
12
- * Redistributions in binary form must reproduce the above
13
- copyright notice, this list of conditions and the following disclaimer
14
- in the documentation and/or other materials provided with the
15
- distribution.
16
-
17
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
-
29
- You can contact the author at :
30
- - xxHash source repository : http://code.google.com/p/xxhash/
2
+ * xxHash - Fast Hash algorithm
3
+ * Copyright (C) 2012-2016, Yann Collet
4
+ *
5
+ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are
9
+ * met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above
14
+ * copyright notice, this list of conditions and the following disclaimer
15
+ * in the documentation and/or other materials provided with the
16
+ * distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ *
30
+ * You can contact the author at :
31
+ * - xxHash homepage: http://www.xxhash.com
32
+ * - xxHash source repository : https://github.com/Cyan4973/xxHash
31
33
  */
32
34
 
33
35
 
34
- //**************************************
35
- // Tuning parameters
36
- //**************************************
37
- // Unaligned memory access is automatically enabled for "common" CPU, such as x86.
38
- // For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected.
39
- // If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance.
40
- // You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32).
41
- #if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
42
- # define XXH_USE_UNALIGNED_ACCESS 1
36
+ /* *************************************
37
+ * Tuning parameters
38
+ ***************************************/
39
+ /*!XXH_FORCE_MEMORY_ACCESS :
40
+ * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
41
+ * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
42
+ * The below switch allow to select different access method for improved performance.
43
+ * Method 0 (default) : use `memcpy()`. Safe and portable.
44
+ * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
45
+ * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
46
+ * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.
47
+ * It can generate buggy code on targets which do not support unaligned memory accesses.
48
+ * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
49
+ * See http://stackoverflow.com/a/32095106/646947 for details.
50
+ * Prefer these methods in priority order (0 > 1 > 2)
51
+ */
52
+ #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
53
+ # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
54
+ # define XXH_FORCE_MEMORY_ACCESS 2
55
+ # elif defined(__INTEL_COMPILER) || \
56
+ (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
57
+ # define XXH_FORCE_MEMORY_ACCESS 1
58
+ # endif
43
59
  #endif
44
60
 
45
- // XXH_ACCEPT_NULL_INPUT_POINTER :
46
- // If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
47
- // When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
48
- // This option has a very small performance cost (only measurable on small inputs).
49
- // By default, this option is disabled. To enable it, uncomment below define :
50
- //#define XXH_ACCEPT_NULL_INPUT_POINTER 1
51
-
52
- // XXH_FORCE_NATIVE_FORMAT :
53
- // By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
54
- // Results are therefore identical for little-endian and big-endian CPU.
55
- // This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
56
- // Should endian-independance be of no importance for your application, you may set the #define below to 1.
57
- // It will improve speed for Big-endian CPU.
58
- // This option has no impact on Little_Endian CPU.
59
- #define XXH_FORCE_NATIVE_FORMAT 0
60
-
61
-
62
- //**************************************
63
- // Compiler Specific Options
64
- //**************************************
65
- // Disable some Visual warning messages
66
- #ifdef _MSC_VER // Visual Studio
67
- # pragma warning(disable : 4127) // disable: C4127: conditional expression is constant
61
+ /*!XXH_ACCEPT_NULL_INPUT_POINTER :
62
+ * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
63
+ * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
64
+ * By default, this option is disabled. To enable it, uncomment below define :
65
+ */
66
+ /* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */
67
+
68
+ /*!XXH_FORCE_NATIVE_FORMAT :
69
+ * By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
70
+ * Results are therefore identical for little-endian and big-endian CPU.
71
+ * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
72
+ * Should endian-independance be of no importance for your application, you may set the #define below to 1,
73
+ * to improve speed for Big-endian CPU.
74
+ * This option has no impact on Little_Endian CPU.
75
+ */
76
+ #ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */
77
+ # define XXH_FORCE_NATIVE_FORMAT 0
68
78
  #endif
69
79
 
70
- #ifdef _MSC_VER // Visual Studio
71
- # define forceinline static __forceinline
72
- #else
73
- # ifdef __GNUC__
74
- # define forceinline static inline __attribute__((always_inline))
80
+ /*!XXH_FORCE_ALIGN_CHECK :
81
+ * This is a minor performance trick, only useful with lots of very small keys.
82
+ * It means : check for aligned/unaligned input.
83
+ * The check costs one initial branch per hash; set to 0 when the input data
84
+ * is guaranteed to be aligned.
85
+ */
86
+ #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
87
+ # if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
88
+ # define XXH_FORCE_ALIGN_CHECK 0
75
89
  # else
76
- # define forceinline static inline
90
+ # define XXH_FORCE_ALIGN_CHECK 1
77
91
  # endif
78
92
  #endif
79
93
 
80
94
 
81
- //**************************************
82
- // Includes & Memory related functions
83
- //**************************************
84
- #include "libxxhash.h"
85
- // Modify the local functions below should you wish to use some other memory related routines
86
- // for malloc(), free()
95
+ /* *************************************
96
+ * Includes & Memory related functions
97
+ ***************************************/
98
+ /* Modify the local functions below should you wish to use some other memory routines */
99
+ /* for malloc(), free() */
87
100
  #include <stdlib.h>
88
- forceinline void* XXH_malloc(size_t s) { return malloc(s); }
89
- forceinline void XXH_free (void* p) { free(p); }
90
- // for memcpy()
101
+ static void* XXH_malloc(size_t s) { return malloc(s); }
102
+ static void XXH_free (void* p) { free(p); }
103
+ /* for memcpy() */
91
104
  #include <string.h>
92
- forceinline void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
93
-
94
-
95
- //**************************************
96
- // Basic Types
97
- //**************************************
98
- #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
99
- # include <stdint.h>
100
- typedef uint8_t BYTE;
101
- typedef uint16_t U16;
102
- typedef uint32_t U32;
103
- typedef int32_t S32;
104
- typedef uint64_t U64;
105
- #else
106
- typedef unsigned char BYTE;
107
- typedef unsigned short U16;
108
- typedef unsigned int U32;
109
- typedef signed int S32;
110
- typedef unsigned long long U64;
111
- #endif
105
+ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
106
+
107
+ #define XXH_STATIC_LINKING_ONLY
108
+ #include "xxhash.h"
112
109
 
113
- #if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS)
114
- # define _PACKED __attribute__ ((packed))
115
- #else
116
- # define _PACKED
117
- #endif
118
110
 
119
- #if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
120
- # ifdef __IBMC__
121
- # pragma pack(1)
111
+ /* *************************************
112
+ * Compiler Specific Options
113
+ ***************************************/
114
+ #ifdef _MSC_VER /* Visual Studio */
115
+ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
116
+ # define FORCE_INLINE static __forceinline
117
+ #else
118
+ # if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
119
+ # ifdef __GNUC__
120
+ # define FORCE_INLINE static inline __attribute__((always_inline))
121
+ # else
122
+ # define FORCE_INLINE static inline
123
+ # endif
122
124
  # else
123
- # pragma pack(push, 1)
124
- # endif
125
+ # define FORCE_INLINE static
126
+ # endif /* __STDC_VERSION__ */
125
127
  #endif
126
128
 
127
- typedef struct _U32_S { U32 v; } _PACKED U32_S;
128
129
 
129
- #if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
130
- # pragma pack(pop)
130
+ /* *************************************
131
+ * Basic Types
132
+ ***************************************/
133
+ #ifndef MEM_MODULE
134
+ # if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
135
+ # include <stdint.h>
136
+ typedef uint8_t BYTE;
137
+ typedef uint16_t U16;
138
+ typedef uint32_t U32;
139
+ typedef int32_t S32;
140
+ # else
141
+ typedef unsigned char BYTE;
142
+ typedef unsigned short U16;
143
+ typedef unsigned int U32;
144
+ typedef signed int S32;
145
+ # endif
131
146
  #endif
132
147
 
133
- #define A32(x) (((U32_S *)(x))->v)
148
+ #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
149
+
150
+ /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
151
+ static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
152
+
153
+ #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
154
+
155
+ /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
156
+ /* currently only defined for gcc and icc */
157
+ typedef union { U32 u32; } __attribute__((packed)) unalign;
158
+ static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
159
+
160
+ #else
161
+
162
+ /* portable and safe solution. Generally efficient.
163
+ * see : http://stackoverflow.com/a/32095106/646947
164
+ */
165
+ static U32 XXH_read32(const void* memPtr)
166
+ {
167
+ U32 val;
168
+ memcpy(&val, memPtr, sizeof(val));
169
+ return val;
170
+ }
171
+
172
+ #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
134
173
 
135
174
 
136
- //***************************************
137
- // Compiler-specific Functions and Macros
138
- //***************************************
175
+ /* ****************************************
176
+ * Compiler-specific Functions and Macros
177
+ ******************************************/
139
178
  #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
140
179
 
141
- // Note : although _rotl exists for minGW (GCC under windows), performance seems poor
180
+ /* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
142
181
  #if defined(_MSC_VER)
143
182
  # define XXH_rotl32(x,r) _rotl(x,r)
183
+ # define XXH_rotl64(x,r) _rotl64(x,r)
144
184
  #else
145
185
  # define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
186
+ # define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
146
187
  #endif
147
188
 
148
- #if defined(_MSC_VER) // Visual Studio
189
+ #if defined(_MSC_VER) /* Visual Studio */
149
190
  # define XXH_swap32 _byteswap_ulong
150
191
  #elif GCC_VERSION >= 403
151
192
  # define XXH_swap32 __builtin_bswap32
152
193
  #else
153
- static inline U32 XXH_swap32 (U32 x) {
194
+ static U32 XXH_swap32 (U32 x)
195
+ {
154
196
  return ((x << 24) & 0xff000000 ) |
155
- ((x << 8) & 0x00ff0000 ) |
156
- ((x >> 8) & 0x0000ff00 ) |
157
- ((x >> 24) & 0x000000ff );}
197
+ ((x << 8) & 0x00ff0000 ) |
198
+ ((x >> 8) & 0x0000ff00 ) |
199
+ ((x >> 24) & 0x000000ff );
200
+ }
158
201
  #endif
159
202
 
160
203
 
161
- //**************************************
162
- // Constants
163
- //**************************************
164
- #define PRIME32_1 2654435761U
165
- #define PRIME32_2 2246822519U
166
- #define PRIME32_3 3266489917U
167
- #define PRIME32_4 668265263U
168
- #define PRIME32_5 374761393U
169
-
170
-
171
- //**************************************
172
- // Architecture Macros
173
- //**************************************
204
+ /* *************************************
205
+ * Architecture Macros
206
+ ***************************************/
174
207
  typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
175
- #ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch
176
- static const int one = 1;
177
- # define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one))
178
- #endif
179
208
 
180
-
181
- //**************************************
182
- // Macros
183
- //**************************************
184
- #define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations
209
+ /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
210
+ #ifndef XXH_CPU_LITTLE_ENDIAN
211
+ static const int g_one = 1;
212
+ # define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one))
213
+ #endif
185
214
 
186
215
 
187
- //****************************
188
- // Memory reads
189
- //****************************
216
+ /* ***************************
217
+ * Memory reads
218
+ *****************************/
190
219
  typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
191
220
 
192
- forceinline U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align)
221
+ FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
193
222
  {
194
223
  if (align==XXH_unaligned)
195
- return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
224
+ return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
196
225
  else
197
- return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr);
226
+ return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
198
227
  }
199
228
 
200
- forceinline U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); }
229
+ FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
230
+ {
231
+ return XXH_readLE32_align(ptr, endian, XXH_unaligned);
232
+ }
201
233
 
234
+ static U32 XXH_readBE32(const void* ptr)
235
+ {
236
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
237
+ }
238
+
239
+
240
+ /* *************************************
241
+ * Macros
242
+ ***************************************/
243
+ #define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
244
+ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
245
+
246
+
247
+ /* *******************************************************************
248
+ * 32-bits hash functions
249
+ *********************************************************************/
250
+ static const U32 PRIME32_1 = 2654435761U;
251
+ static const U32 PRIME32_2 = 2246822519U;
252
+ static const U32 PRIME32_3 = 3266489917U;
253
+ static const U32 PRIME32_4 = 668265263U;
254
+ static const U32 PRIME32_5 = 374761393U;
255
+
256
+ static U32 XXH32_round(U32 seed, U32 input)
257
+ {
258
+ seed += input * PRIME32_2;
259
+ seed = XXH_rotl32(seed, 13);
260
+ seed *= PRIME32_1;
261
+ return seed;
262
+ }
202
263
 
203
- //****************************
204
- // Simple Hash Functions
205
- //****************************
206
- forceinline U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_endianess endian, XXH_alignment align)
264
+ FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
207
265
  {
208
266
  const BYTE* p = (const BYTE*)input;
209
- const BYTE* const bEnd = p + len;
267
+ const BYTE* bEnd = p + len;
210
268
  U32 h32;
269
+ #define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
211
270
 
212
271
  #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
213
- if (p==NULL) { len=0; p=(const BYTE*)(size_t)16; }
272
+ if (p==NULL) {
273
+ len=0;
274
+ bEnd=p=(const BYTE*)(size_t)16;
275
+ }
214
276
  #endif
215
277
 
216
- if (len>=16)
217
- {
278
+ if (len>=16) {
218
279
  const BYTE* const limit = bEnd - 16;
219
280
  U32 v1 = seed + PRIME32_1 + PRIME32_2;
220
281
  U32 v2 = seed + PRIME32_2;
221
282
  U32 v3 = seed + 0;
222
283
  U32 v4 = seed - PRIME32_1;
223
284
 
224
- do
225
- {
226
- v1 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
227
- v2 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
228
- v3 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
229
- v4 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
285
+ do {
286
+ v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;
287
+ v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;
288
+ v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;
289
+ v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;
230
290
  } while (p<=limit);
231
291
 
232
292
  h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
233
- }
234
- else
235
- {
293
+ } else {
236
294
  h32 = seed + PRIME32_5;
237
295
  }
238
296
 
239
297
  h32 += (U32) len;
240
298
 
241
- while (p<=bEnd-4)
242
- {
243
- h32 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_3;
299
+ while (p+4<=bEnd) {
300
+ h32 += XXH_get32bits(p) * PRIME32_3;
244
301
  h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
245
302
  p+=4;
246
303
  }
247
304
 
248
- while (p<bEnd)
249
- {
305
+ while (p<bEnd) {
250
306
  h32 += (*p) * PRIME32_5;
251
307
  h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
252
308
  p++;
@@ -262,25 +318,24 @@ forceinline U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_end
262
318
  }
263
319
 
264
320
 
265
- U32 XXH32(const void* input, int len, U32 seed)
321
+ XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)
266
322
  {
267
323
  #if 0
268
- // Simple version, good for code maintenance, but unfortunately slow for small inputs
269
- void* state = XXH32_init(seed);
324
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
325
+ XXH32_CREATESTATE_STATIC(state);
326
+ XXH32_reset(state, seed);
270
327
  XXH32_update(state, input, len);
271
328
  return XXH32_digest(state);
272
329
  #else
273
330
  XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
274
331
 
275
- # if !defined(XXH_USE_UNALIGNED_ACCESS)
276
- if ((((size_t)input) & 3)) // Input is aligned, let's leverage the speed advantage
277
- {
278
- if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
279
- return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
280
- else
281
- return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
282
- }
283
- # endif
332
+ if (XXH_FORCE_ALIGN_CHECK) {
333
+ if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
334
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
335
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
336
+ else
337
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
338
+ } }
284
339
 
285
340
  if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
286
341
  return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
@@ -290,55 +345,39 @@ U32 XXH32(const void* input, int len, U32 seed)
290
345
  }
291
346
 
292
347
 
293
- //****************************
294
- // Advanced Hash Functions
295
- //****************************
296
-
297
- struct XXH_state32_t
298
- {
299
- U64 total_len;
300
- U32 seed;
301
- U32 v1;
302
- U32 v2;
303
- U32 v3;
304
- U32 v4;
305
- int memsize;
306
- char memory[16];
307
- };
308
348
 
349
+ /*====== Hash streaming ======*/
309
350
 
310
- int XXH32_sizeofState()
351
+ XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
311
352
  {
312
- XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t)); // A compilation error here means XXH32_SIZEOFSTATE is not large enough
313
- return sizeof(struct XXH_state32_t);
353
+ return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
314
354
  }
315
-
316
-
317
- XXH_errorcode XXH32_resetState(void* state_in, U32 seed)
355
+ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
318
356
  {
319
- struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
320
- state->seed = seed;
321
- state->v1 = seed + PRIME32_1 + PRIME32_2;
322
- state->v2 = seed + PRIME32_2;
323
- state->v3 = seed + 0;
324
- state->v4 = seed - PRIME32_1;
325
- state->total_len = 0;
326
- state->memsize = 0;
357
+ XXH_free(statePtr);
327
358
  return XXH_OK;
328
359
  }
329
360
 
361
+ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState)
362
+ {
363
+ memcpy(dstState, srcState, sizeof(*dstState));
364
+ }
330
365
 
331
- void* XXH32_init (U32 seed)
366
+ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)
332
367
  {
333
- void* state = XXH_malloc (sizeof(struct XXH_state32_t));
334
- XXH32_resetState(state, seed);
335
- return state;
368
+ XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
369
+ memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */
370
+ state.v1 = seed + PRIME32_1 + PRIME32_2;
371
+ state.v2 = seed + PRIME32_2;
372
+ state.v3 = seed + 0;
373
+ state.v4 = seed - PRIME32_1;
374
+ memcpy(statePtr, &state, sizeof(state));
375
+ return XXH_OK;
336
376
  }
337
377
 
338
378
 
339
- forceinline XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian)
379
+ FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
340
380
  {
341
- struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
342
381
  const BYTE* p = (const BYTE*)input;
343
382
  const BYTE* const bEnd = p + len;
344
383
 
@@ -346,43 +385,39 @@ forceinline XXH_errorcode XXH32_update_endian (void* state_in, const void* input
346
385
  if (input==NULL) return XXH_ERROR;
347
386
  #endif
348
387
 
349
- state->total_len += len;
388
+ state->total_len_32 += (unsigned)len;
389
+ state->large_len |= (len>=16) | (state->total_len_32>=16);
350
390
 
351
- if (state->memsize + len < 16) // fill in tmp buffer
352
- {
353
- XXH_memcpy(state->memory + state->memsize, input, len);
354
- state->memsize += len;
391
+ if (state->memsize + len < 16) { /* fill in tmp buffer */
392
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
393
+ state->memsize += (unsigned)len;
355
394
  return XXH_OK;
356
395
  }
357
396
 
358
- if (state->memsize) // some data left from previous update
359
- {
360
- XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize);
361
- {
362
- const U32* p32 = (const U32*)state->memory;
363
- state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;
364
- state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++;
365
- state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;
366
- state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;
397
+ if (state->memsize) { /* some data left from previous update */
398
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
399
+ { const U32* p32 = state->mem32;
400
+ state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;
401
+ state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;
402
+ state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;
403
+ state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++;
367
404
  }
368
405
  p += 16-state->memsize;
369
406
  state->memsize = 0;
370
407
  }
371
408
 
372
- if (p <= bEnd-16)
373
- {
409
+ if (p <= bEnd-16) {
374
410
  const BYTE* const limit = bEnd - 16;
375
411
  U32 v1 = state->v1;
376
412
  U32 v2 = state->v2;
377
413
  U32 v3 = state->v3;
378
414
  U32 v4 = state->v4;
379
415
 
380
- do
381
- {
382
- v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
383
- v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
384
- v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
385
- v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
416
+ do {
417
+ v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;
418
+ v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;
419
+ v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;
420
+ v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;
386
421
  } while (p<=limit);
387
422
 
388
423
  state->v1 = v1;
@@ -391,16 +426,15 @@ forceinline XXH_errorcode XXH32_update_endian (void* state_in, const void* input
391
426
  state->v4 = v4;
392
427
  }
393
428
 
394
- if (p < bEnd)
395
- {
396
- XXH_memcpy(state->memory, p, bEnd-p);
397
- state->memsize = (int)(bEnd-p);
429
+ if (p < bEnd) {
430
+ XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
431
+ state->memsize = (unsigned)(bEnd-p);
398
432
  }
399
433
 
400
434
  return XXH_OK;
401
435
  }
402
436
 
403
- XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
437
+ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
404
438
  {
405
439
  XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
406
440
 
@@ -412,35 +446,29 @@ XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
412
446
 
413
447
 
414
448
 
415
- forceinline U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian)
449
+ FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
416
450
  {
417
- struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
418
- const BYTE * p = (const BYTE*)state->memory;
419
- BYTE* bEnd = (BYTE*)state->memory + state->memsize;
451
+ const BYTE * p = (const BYTE*)state->mem32;
452
+ const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize;
420
453
  U32 h32;
421
454
 
422
- if (state->total_len >= 16)
423
- {
455
+ if (state->large_len) {
424
456
  h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
425
- }
426
- else
427
- {
428
- h32 = state->seed + PRIME32_5;
457
+ } else {
458
+ h32 = state->v3 /* == seed */ + PRIME32_5;
429
459
  }
430
460
 
431
- h32 += (U32) state->total_len;
461
+ h32 += state->total_len_32;
432
462
 
433
- while (p<=bEnd-4)
434
- {
435
- h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3;
463
+ while (p+4<=bEnd) {
464
+ h32 += XXH_readLE32(p, endian) * PRIME32_3;
436
465
  h32 = XXH_rotl32(h32, 17) * PRIME32_4;
437
466
  p+=4;
438
467
  }
439
468
 
440
- while (p<bEnd)
441
- {
469
+ while (p<bEnd) {
442
470
  h32 += (*p) * PRIME32_5;
443
- h32 = XXH_rotl32(h32, 11) * PRIME32_1;
471
+ h32 = XXH_rotl32(h32, 11) * PRIME32_1;
444
472
  p++;
445
473
  }
446
474
 
@@ -454,22 +482,409 @@ forceinline U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess e
454
482
  }
455
483
 
456
484
 
457
- U32 XXH32_intermediateDigest (void* state_in)
485
+ XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
458
486
  {
459
487
  XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
460
488
 
461
489
  if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
462
- return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian);
490
+ return XXH32_digest_endian(state_in, XXH_littleEndian);
491
+ else
492
+ return XXH32_digest_endian(state_in, XXH_bigEndian);
493
+ }
494
+
495
+
496
+ /*====== Canonical representation ======*/
497
+
498
+ /*! Default XXH result types are basic unsigned 32 and 64 bits.
499
+ * The canonical representation follows human-readable write convention, aka big-endian (large digits first).
500
+ * These functions allow transformation of hash result into and from its canonical format.
501
+ * This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs.
502
+ */
503
+
504
+ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
505
+ {
506
+ XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
507
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
508
+ memcpy(dst, &hash, sizeof(*dst));
509
+ }
510
+
511
+ XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
512
+ {
513
+ return XXH_readBE32(src);
514
+ }
515
+
516
+
517
+ #ifndef XXH_NO_LONG_LONG
518
+
519
+ /* *******************************************************************
520
+ * 64-bits hash functions
521
+ *********************************************************************/
522
+
523
+ /*====== Memory access ======*/
524
+
525
+ #ifndef MEM_MODULE
526
+ # define MEM_MODULE
527
+ # if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
528
+ # include <stdint.h>
529
+ typedef uint64_t U64;
530
+ # else
531
+ typedef unsigned long long U64; /* if your compiler doesn't support unsigned long long, replace by another 64-bit type here. Note that xxhash.h will also need to be updated. */
532
+ # endif
533
+ #endif
534
+
535
+
536
+ #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
537
+
538
+ /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
539
+ static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
540
+
541
+ #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
542
+
543
+ /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
544
+ /* currently only defined for gcc and icc */
545
+ typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64;
546
+
547
+ static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; }
548
+
549
+ #else
550
+
551
+ /* portable and safe solution. Generally efficient.
552
+ * see : http://stackoverflow.com/a/32095106/646947
553
+ */
554
+
555
+ static U64 XXH_read64(const void* memPtr)
556
+ {
557
+ U64 val;
558
+ memcpy(&val, memPtr, sizeof(val));
559
+ return val;
560
+ }
561
+
562
+ #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
563
+
564
+ #if defined(_MSC_VER) /* Visual Studio */
565
+ # define XXH_swap64 _byteswap_uint64
566
+ #elif GCC_VERSION >= 403
567
+ # define XXH_swap64 __builtin_bswap64
568
+ #else
569
+ static U64 XXH_swap64 (U64 x)
570
+ {
571
+ return ((x << 56) & 0xff00000000000000ULL) |
572
+ ((x << 40) & 0x00ff000000000000ULL) |
573
+ ((x << 24) & 0x0000ff0000000000ULL) |
574
+ ((x << 8) & 0x000000ff00000000ULL) |
575
+ ((x >> 8) & 0x00000000ff000000ULL) |
576
+ ((x >> 24) & 0x0000000000ff0000ULL) |
577
+ ((x >> 40) & 0x000000000000ff00ULL) |
578
+ ((x >> 56) & 0x00000000000000ffULL);
579
+ }
580
+ #endif
581
+
582
+ FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
583
+ {
584
+ if (align==XXH_unaligned)
585
+ return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
463
586
  else
464
- return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian);
587
+ return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
465
588
  }
466
589
 
590
+ FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
591
+ {
592
+ return XXH_readLE64_align(ptr, endian, XXH_unaligned);
593
+ }
467
594
 
468
- U32 XXH32_digest (void* state_in)
595
+ static U64 XXH_readBE64(const void* ptr)
469
596
  {
470
- U32 h32 = XXH32_intermediateDigest(state_in);
597
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
598
+ }
471
599
 
472
- XXH_free(state_in);
473
600
 
474
- return h32;
601
+ /*====== xxh64 ======*/
602
+
603
+ static const U64 PRIME64_1 = 11400714785074694791ULL;
604
+ static const U64 PRIME64_2 = 14029467366897019727ULL;
605
+ static const U64 PRIME64_3 = 1609587929392839161ULL;
606
+ static const U64 PRIME64_4 = 9650029242287828579ULL;
607
+ static const U64 PRIME64_5 = 2870177450012600261ULL;
608
+
609
+ static U64 XXH64_round(U64 acc, U64 input)
610
+ {
611
+ acc += input * PRIME64_2;
612
+ acc = XXH_rotl64(acc, 31);
613
+ acc *= PRIME64_1;
614
+ return acc;
615
+ }
616
+
617
+ static U64 XXH64_mergeRound(U64 acc, U64 val)
618
+ {
619
+ val = XXH64_round(0, val);
620
+ acc ^= val;
621
+ acc = acc * PRIME64_1 + PRIME64_4;
622
+ return acc;
623
+ }
624
+
625
+ FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
626
+ {
627
+ const BYTE* p = (const BYTE*)input;
628
+ const BYTE* const bEnd = p + len;
629
+ U64 h64;
630
+ #define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
631
+
632
+ #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
633
+ if (p==NULL) {
634
+ len=0;
635
+ bEnd=p=(const BYTE*)(size_t)32;
636
+ }
637
+ #endif
638
+
639
+ if (len>=32) {
640
+ const BYTE* const limit = bEnd - 32;
641
+ U64 v1 = seed + PRIME64_1 + PRIME64_2;
642
+ U64 v2 = seed + PRIME64_2;
643
+ U64 v3 = seed + 0;
644
+ U64 v4 = seed - PRIME64_1;
645
+
646
+ do {
647
+ v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;
648
+ v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;
649
+ v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;
650
+ v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;
651
+ } while (p<=limit);
652
+
653
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
654
+ h64 = XXH64_mergeRound(h64, v1);
655
+ h64 = XXH64_mergeRound(h64, v2);
656
+ h64 = XXH64_mergeRound(h64, v3);
657
+ h64 = XXH64_mergeRound(h64, v4);
658
+
659
+ } else {
660
+ h64 = seed + PRIME64_5;
661
+ }
662
+
663
+ h64 += (U64) len;
664
+
665
+ while (p+8<=bEnd) {
666
+ U64 const k1 = XXH64_round(0, XXH_get64bits(p));
667
+ h64 ^= k1;
668
+ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
669
+ p+=8;
670
+ }
671
+
672
+ if (p+4<=bEnd) {
673
+ h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
674
+ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
675
+ p+=4;
676
+ }
677
+
678
+ while (p<bEnd) {
679
+ h64 ^= (*p) * PRIME64_5;
680
+ h64 = XXH_rotl64(h64, 11) * PRIME64_1;
681
+ p++;
682
+ }
683
+
684
+ h64 ^= h64 >> 33;
685
+ h64 *= PRIME64_2;
686
+ h64 ^= h64 >> 29;
687
+ h64 *= PRIME64_3;
688
+ h64 ^= h64 >> 32;
689
+
690
+ return h64;
691
+ }
692
+
693
+
694
+ XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
695
+ {
696
+ #if 0
697
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
698
+ XXH64_CREATESTATE_STATIC(state);
699
+ XXH64_reset(state, seed);
700
+ XXH64_update(state, input, len);
701
+ return XXH64_digest(state);
702
+ #else
703
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
704
+
705
+ if (XXH_FORCE_ALIGN_CHECK) {
706
+ if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
707
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
708
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
709
+ else
710
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
711
+ } }
712
+
713
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
714
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
715
+ else
716
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
717
+ #endif
718
+ }
719
+
720
+ /*====== Hash Streaming ======*/
721
+
722
+ XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
723
+ {
724
+ return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
725
+ }
726
+ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
727
+ {
728
+ XXH_free(statePtr);
729
+ return XXH_OK;
730
+ }
731
+
732
+ XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState)
733
+ {
734
+ memcpy(dstState, srcState, sizeof(*dstState));
735
+ }
736
+
737
+ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)
738
+ {
739
+ XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
740
+ memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */
741
+ state.v1 = seed + PRIME64_1 + PRIME64_2;
742
+ state.v2 = seed + PRIME64_2;
743
+ state.v3 = seed + 0;
744
+ state.v4 = seed - PRIME64_1;
745
+ memcpy(statePtr, &state, sizeof(state));
746
+ return XXH_OK;
747
+ }
748
+
749
+ FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
750
+ {
751
+ const BYTE* p = (const BYTE*)input;
752
+ const BYTE* const bEnd = p + len;
753
+
754
+ #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
755
+ if (input==NULL) return XXH_ERROR;
756
+ #endif
757
+
758
+ state->total_len += len;
759
+
760
+ if (state->memsize + len < 32) { /* fill in tmp buffer */
761
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
762
+ state->memsize += (U32)len;
763
+ return XXH_OK;
764
+ }
765
+
766
+ if (state->memsize) { /* tmp buffer is full */
767
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
768
+ state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));
769
+ state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));
770
+ state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));
771
+ state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));
772
+ p += 32-state->memsize;
773
+ state->memsize = 0;
774
+ }
775
+
776
+ if (p+32 <= bEnd) {
777
+ const BYTE* const limit = bEnd - 32;
778
+ U64 v1 = state->v1;
779
+ U64 v2 = state->v2;
780
+ U64 v3 = state->v3;
781
+ U64 v4 = state->v4;
782
+
783
+ do {
784
+ v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;
785
+ v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;
786
+ v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;
787
+ v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;
788
+ } while (p<=limit);
789
+
790
+ state->v1 = v1;
791
+ state->v2 = v2;
792
+ state->v3 = v3;
793
+ state->v4 = v4;
794
+ }
795
+
796
+ if (p < bEnd) {
797
+ XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
798
+ state->memsize = (unsigned)(bEnd-p);
799
+ }
800
+
801
+ return XXH_OK;
802
+ }
803
+
804
+ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
805
+ {
806
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
807
+
808
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
809
+ return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
810
+ else
811
+ return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
475
812
  }
813
+
814
+ FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
815
+ {
816
+ const BYTE * p = (const BYTE*)state->mem64;
817
+ const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize;
818
+ U64 h64;
819
+
820
+ if (state->total_len >= 32) {
821
+ U64 const v1 = state->v1;
822
+ U64 const v2 = state->v2;
823
+ U64 const v3 = state->v3;
824
+ U64 const v4 = state->v4;
825
+
826
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
827
+ h64 = XXH64_mergeRound(h64, v1);
828
+ h64 = XXH64_mergeRound(h64, v2);
829
+ h64 = XXH64_mergeRound(h64, v3);
830
+ h64 = XXH64_mergeRound(h64, v4);
831
+ } else {
832
+ h64 = state->v3 + PRIME64_5;
833
+ }
834
+
835
+ h64 += (U64) state->total_len;
836
+
837
+ while (p+8<=bEnd) {
838
+ U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian));
839
+ h64 ^= k1;
840
+ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
841
+ p+=8;
842
+ }
843
+
844
+ if (p+4<=bEnd) {
845
+ h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
846
+ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
847
+ p+=4;
848
+ }
849
+
850
+ while (p<bEnd) {
851
+ h64 ^= (*p) * PRIME64_5;
852
+ h64 = XXH_rotl64(h64, 11) * PRIME64_1;
853
+ p++;
854
+ }
855
+
856
+ h64 ^= h64 >> 33;
857
+ h64 *= PRIME64_2;
858
+ h64 ^= h64 >> 29;
859
+ h64 *= PRIME64_3;
860
+ h64 ^= h64 >> 32;
861
+
862
+ return h64;
863
+ }
864
+
865
+ XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
866
+ {
867
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
868
+
869
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
870
+ return XXH64_digest_endian(state_in, XXH_littleEndian);
871
+ else
872
+ return XXH64_digest_endian(state_in, XXH_bigEndian);
873
+ }
874
+
875
+
876
+ /*====== Canonical representation ======*/
877
+
878
+ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
879
+ {
880
+ XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
881
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
882
+ memcpy(dst, &hash, sizeof(*dst));
883
+ }
884
+
885
+ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
886
+ {
887
+ return XXH_readBE64(src);
888
+ }
889
+
890
+ #endif /* XXH_NO_LONG_LONG */