xref: /reactos/drivers/filesystems/btrfs/xxhash.c (revision 682f85ad)
1 /*
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
33 */
34 
35 
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) && !defined(WIN32)) || \
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
59 #endif
60 
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
78 #endif
79 
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
89 #  else
90 #    define XXH_FORCE_ALIGN_CHECK 1
91 #  endif
92 #endif
93 
94 
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() */
100 #include <stdlib.h>
101 #include <stddef.h>     /* size_t */
102 #ifndef __REACTOS__
103 #include <ntifs.h>
104 #include <ntddk.h>
105 #endif // __REACTOS__
106 
107 #ifndef _USRDLL
108 #ifdef __REACTOS__
109 #include <ntifs.h>
110 #include <ntddk.h>
111 #endif // __REACTOS__
112 
113 #define XXH_ALLOC_TAG 0x32485858 // "XXH "
114 
115 static void* XXH_malloc(size_t s) {
116     return ExAllocatePoolWithTag(PagedPool, s, XXH_ALLOC_TAG);
117 }
118 
119 static void XXH_free(void* p) {
120     ExFreePool(p);
121 }
122 
123 #else
124 #ifndef __REACTOS__
125 static void* XXH_malloc(size_t s) {
126     return malloc(s);
127 }
128 
129 static void XXH_free(void* p) {
130     free(p);
131 }
132 #else
133 #include <ndk/rtlfuncs.h>
134 
135 static void* XXH_malloc(size_t s) {
136     return RtlAllocateHeap(RtlGetProcessHeap(), 0, s);
137 }
138 
139 static void XXH_free(void* p) {
140     RtlFreeHeap(RtlGetProcessHeap(), 0, p);
141 }
142 #endif // __REACTOS__
143 #endif
144 
145 /* for memcpy() */
146 #include <string.h>
147 static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
148 
149 #ifndef XXH_STATIC_LINKING_ONLY
150 #  define XXH_STATIC_LINKING_ONLY
151 #endif
152 #include "xxhash.h"
153 
154 
155 /* *************************************
156 *  Compiler Specific Options
157 ***************************************/
158 #if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */
159 #  define INLINE_KEYWORD inline
160 #else
161 #  define INLINE_KEYWORD
162 #endif
163 
164 #if defined(__GNUC__)
165 #  define FORCE_INLINE_ATTR __attribute__((always_inline))
166 #elif defined(_MSC_VER)
167 #  define FORCE_INLINE_ATTR __forceinline
168 #else
169 #  define FORCE_INLINE_ATTR
170 #endif
171 
172 #define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
173 
174 
175 #ifdef _MSC_VER
176 #  pragma warning(disable : 4127)      /* disable: C4127: conditional expression is constant */
177 #endif
178 
179 
180 /* *************************************
181 *  Basic Types
182 ***************************************/
183 #ifndef MEM_MODULE
184 # define MEM_MODULE
185 # if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
186 #   include <stdint.h>
187     typedef uint8_t  BYTE;
188     typedef uint16_t U16;
189     typedef uint32_t U32;
190     typedef  int32_t S32;
191     typedef uint64_t U64;
192 #  else
193     typedef unsigned char      BYTE;
194     typedef unsigned short     U16;
195     typedef unsigned int       U32;
196     typedef   signed int       S32;
197     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. */
198 #  endif
199 #endif
200 
201 
202 #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
203 
204 /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
205 static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
206 static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
207 
208 #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
209 
210 /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
211 /* currently only defined for gcc and icc */
212 typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign;
213 
214 static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
215 static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
216 
217 #else
218 
219 /* portable and safe solution. Generally efficient.
220  * see : http://stackoverflow.com/a/32095106/646947
221  */
222 
223 static U32 XXH_read32(const void* memPtr)
224 {
225     U32 val;
226     memcpy(&val, memPtr, sizeof(val));
227     return val;
228 }
229 
230 static U64 XXH_read64(const void* memPtr)
231 {
232     U64 val;
233     memcpy(&val, memPtr, sizeof(val));
234     return val;
235 }
236 
237 #endif   /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
238 
239 
240 /* ****************************************
241 *  Compiler-specific Functions and Macros
242 ******************************************/
243 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
244 
245 /* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
246 #if defined(_MSC_VER)
247 #  define XXH_rotl32(x,r) _rotl(x,r)
248 #  define XXH_rotl64(x,r) _rotl64(x,r)
249 #else
250 #  define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
251 #  define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
252 #endif
253 
254 #if defined(_MSC_VER)     /* Visual Studio */
255 #  define XXH_swap32 _byteswap_ulong
256 #  define XXH_swap64 _byteswap_uint64
257 #elif GCC_VERSION >= 403
258 #  define XXH_swap32 __builtin_bswap32
259 #  define XXH_swap64 __builtin_bswap64
260 #else
261 static U32 XXH_swap32 (U32 x)
262 {
263     return  ((x << 24) & 0xff000000 ) |
264             ((x <<  8) & 0x00ff0000 ) |
265             ((x >>  8) & 0x0000ff00 ) |
266             ((x >> 24) & 0x000000ff );
267 }
268 static U64 XXH_swap64 (U64 x)
269 {
270     return  ((x << 56) & 0xff00000000000000ULL) |
271             ((x << 40) & 0x00ff000000000000ULL) |
272             ((x << 24) & 0x0000ff0000000000ULL) |
273             ((x << 8)  & 0x000000ff00000000ULL) |
274             ((x >> 8)  & 0x00000000ff000000ULL) |
275             ((x >> 24) & 0x0000000000ff0000ULL) |
276             ((x >> 40) & 0x000000000000ff00ULL) |
277             ((x >> 56) & 0x00000000000000ffULL);
278 }
279 #endif
280 
281 
282 /* *************************************
283 *  Architecture Macros
284 ***************************************/
285 typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
286 
287 /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
288 #ifndef XXH_CPU_LITTLE_ENDIAN
289     static const int g_one = 1;
290 #   define XXH_CPU_LITTLE_ENDIAN   (*(const char*)(&g_one))
291 #endif
292 
293 
294 /* ***************************
295 *  Memory reads
296 *****************************/
297 typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
298 
299 FORCE_INLINE_TEMPLATE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
300 {
301     if (align==XXH_unaligned)
302         return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
303     else
304         return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
305 }
306 
307 FORCE_INLINE_TEMPLATE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
308 {
309     return XXH_readLE32_align(ptr, endian, XXH_unaligned);
310 }
311 
312 static U32 XXH_readBE32(const void* ptr)
313 {
314     return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
315 }
316 
317 FORCE_INLINE_TEMPLATE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
318 {
319     if (align==XXH_unaligned)
320         return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
321     else
322         return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
323 }
324 
325 FORCE_INLINE_TEMPLATE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
326 {
327     return XXH_readLE64_align(ptr, endian, XXH_unaligned);
328 }
329 
330 static U64 XXH_readBE64(const void* ptr)
331 {
332     return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
333 }
334 
335 
336 /* *************************************
337 *  Macros
338 ***************************************/
339 #define XXH_STATIC_ASSERT(c)   { enum { XXH_static_assert = 1/(int)(!!(c)) }; }    /* use only *after* variable declarations */
340 
341 
342 /* *************************************
343 *  Constants
344 ***************************************/
345 static const U32 PRIME32_1 = 2654435761U;
346 static const U32 PRIME32_2 = 2246822519U;
347 static const U32 PRIME32_3 = 3266489917U;
348 static const U32 PRIME32_4 =  668265263U;
349 static const U32 PRIME32_5 =  374761393U;
350 
351 static const U64 PRIME64_1 = 11400714785074694791ULL;
352 static const U64 PRIME64_2 = 14029467366897019727ULL;
353 static const U64 PRIME64_3 =  1609587929392839161ULL;
354 static const U64 PRIME64_4 =  9650029242287828579ULL;
355 static const U64 PRIME64_5 =  2870177450012600261ULL;
356 
357 XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
358 
359 
360 /* **************************
361 *  Utils
362 ****************************/
363 XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState)
364 {
365     memcpy(dstState, srcState, sizeof(*dstState));
366 }
367 
368 XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState)
369 {
370     memcpy(dstState, srcState, sizeof(*dstState));
371 }
372 
373 
374 /* ***************************
375 *  Simple Hash Functions
376 *****************************/
377 
378 static U32 XXH32_round(U32 seed, U32 input)
379 {
380     seed += input * PRIME32_2;
381     seed  = XXH_rotl32(seed, 13);
382     seed *= PRIME32_1;
383     return seed;
384 }
385 
386 FORCE_INLINE_TEMPLATE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
387 {
388     const BYTE* p = (const BYTE*)input;
389     const BYTE* bEnd = p + len;
390     U32 h32;
391 #define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
392 
393 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
394     if (p==NULL) {
395         len=0;
396         bEnd=p=(const BYTE*)(size_t)16;
397     }
398 #endif
399 
400     if (len>=16) {
401         const BYTE* const limit = bEnd - 16;
402         U32 v1 = seed + PRIME32_1 + PRIME32_2;
403         U32 v2 = seed + PRIME32_2;
404         U32 v3 = seed + 0;
405         U32 v4 = seed - PRIME32_1;
406 
407         do {
408             v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;
409             v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;
410             v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;
411             v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;
412         } while (p<=limit);
413 
414         h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
415     } else {
416         h32  = seed + PRIME32_5;
417     }
418 
419     h32 += (U32) len;
420 
421     while (p+4<=bEnd) {
422         h32 += XXH_get32bits(p) * PRIME32_3;
423         h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;
424         p+=4;
425     }
426 
427     while (p<bEnd) {
428         h32 += (*p) * PRIME32_5;
429         h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
430         p++;
431     }
432 
433     h32 ^= h32 >> 15;
434     h32 *= PRIME32_2;
435     h32 ^= h32 >> 13;
436     h32 *= PRIME32_3;
437     h32 ^= h32 >> 16;
438 
439     return h32;
440 }
441 
442 
443 XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)
444 {
445 #if 0
446     /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
447     XXH32_CREATESTATE_STATIC(state);
448     XXH32_reset(state, seed);
449     XXH32_update(state, input, len);
450     return XXH32_digest(state);
451 #else
452     XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
453 
454     if (XXH_FORCE_ALIGN_CHECK) {
455         if ((((size_t)input) & 3) == 0) {   /* Input is 4-bytes aligned, leverage the speed benefit */
456             if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
457                 return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
458             else
459                 return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
460     }   }
461 
462     if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
463         return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
464     else
465         return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
466 #endif
467 }
468 
469 
470 static U64 XXH64_round(U64 acc, U64 input)
471 {
472     acc += input * PRIME64_2;
473     acc  = XXH_rotl64(acc, 31);
474     acc *= PRIME64_1;
475     return acc;
476 }
477 
478 static U64 XXH64_mergeRound(U64 acc, U64 val)
479 {
480     val  = XXH64_round(0, val);
481     acc ^= val;
482     acc  = acc * PRIME64_1 + PRIME64_4;
483     return acc;
484 }
485 
486 FORCE_INLINE_TEMPLATE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
487 {
488     const BYTE* p = (const BYTE*)input;
489     const BYTE* const bEnd = p + len;
490     U64 h64;
491 #define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
492 
493 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
494     if (p==NULL) {
495         len=0;
496         bEnd=p=(const BYTE*)(size_t)32;
497     }
498 #endif
499 
500     if (len>=32) {
501         const BYTE* const limit = bEnd - 32;
502         U64 v1 = seed + PRIME64_1 + PRIME64_2;
503         U64 v2 = seed + PRIME64_2;
504         U64 v3 = seed + 0;
505         U64 v4 = seed - PRIME64_1;
506 
507         do {
508             v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;
509             v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;
510             v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;
511             v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;
512         } while (p<=limit);
513 
514         h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
515         h64 = XXH64_mergeRound(h64, v1);
516         h64 = XXH64_mergeRound(h64, v2);
517         h64 = XXH64_mergeRound(h64, v3);
518         h64 = XXH64_mergeRound(h64, v4);
519 
520     } else {
521         h64  = seed + PRIME64_5;
522     }
523 
524     h64 += (U64) len;
525 
526     while (p+8<=bEnd) {
527         U64 const k1 = XXH64_round(0, XXH_get64bits(p));
528         h64 ^= k1;
529         h64  = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
530         p+=8;
531     }
532 
533     if (p+4<=bEnd) {
534         h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
535         h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
536         p+=4;
537     }
538 
539     while (p<bEnd) {
540         h64 ^= (*p) * PRIME64_5;
541         h64 = XXH_rotl64(h64, 11) * PRIME64_1;
542         p++;
543     }
544 
545     h64 ^= h64 >> 33;
546     h64 *= PRIME64_2;
547     h64 ^= h64 >> 29;
548     h64 *= PRIME64_3;
549     h64 ^= h64 >> 32;
550 
551     return h64;
552 }
553 
554 
555 XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
556 {
557 #if 0
558     /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
559     XXH64_CREATESTATE_STATIC(state);
560     XXH64_reset(state, seed);
561     XXH64_update(state, input, len);
562     return XXH64_digest(state);
563 #else
564     XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
565 
566     if (XXH_FORCE_ALIGN_CHECK) {
567         if ((((size_t)input) & 7)==0) {  /* Input is aligned, let's leverage the speed advantage */
568             if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
569                 return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
570             else
571                 return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
572     }   }
573 
574     if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
575         return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
576     else
577         return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
578 #endif
579 }
580 
581 
582 /* **************************************************
583 *  Advanced Hash Functions
584 ****************************************************/
585 
586 XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
587 {
588     return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
589 }
590 XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
591 {
592     XXH_free(statePtr);
593     return XXH_OK;
594 }
595 
596 XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
597 {
598     return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
599 }
600 XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
601 {
602     XXH_free(statePtr);
603     return XXH_OK;
604 }
605 
606 
607 /*** Hash feed ***/
608 
609 XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)
610 {
611     XXH32_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
612     memset(&state, 0, sizeof(state)-4);   /* do not write into reserved, for future removal */
613     state.v1 = seed + PRIME32_1 + PRIME32_2;
614     state.v2 = seed + PRIME32_2;
615     state.v3 = seed + 0;
616     state.v4 = seed - PRIME32_1;
617     memcpy(statePtr, &state, sizeof(state));
618     return XXH_OK;
619 }
620 
621 
622 XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)
623 {
624     XXH64_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
625     memset(&state, 0, sizeof(state)-8);   /* do not write into reserved, for future removal */
626     state.v1 = seed + PRIME64_1 + PRIME64_2;
627     state.v2 = seed + PRIME64_2;
628     state.v3 = seed + 0;
629     state.v4 = seed - PRIME64_1;
630     memcpy(statePtr, &state, sizeof(state));
631     return XXH_OK;
632 }
633 
634 
635 FORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
636 {
637     const BYTE* p = (const BYTE*)input;
638     const BYTE* const bEnd = p + len;
639 
640 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
641     if (input==NULL) return XXH_ERROR;
642 #endif
643 
644     state->total_len_32 += (unsigned)len;
645     state->large_len |= (len>=16) | (state->total_len_32>=16);
646 
647     if (state->memsize + len < 16)  {   /* fill in tmp buffer */
648         XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
649         state->memsize += (unsigned)len;
650         return XXH_OK;
651     }
652 
653     if (state->memsize) {   /* some data left from previous update */
654         XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
655         {   const U32* p32 = state->mem32;
656             state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;
657             state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;
658             state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;
659             state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++;
660         }
661         p += 16-state->memsize;
662         state->memsize = 0;
663     }
664 
665     if (p <= bEnd-16) {
666         const BYTE* const limit = bEnd - 16;
667         U32 v1 = state->v1;
668         U32 v2 = state->v2;
669         U32 v3 = state->v3;
670         U32 v4 = state->v4;
671 
672         do {
673             v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;
674             v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;
675             v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;
676             v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;
677         } while (p<=limit);
678 
679         state->v1 = v1;
680         state->v2 = v2;
681         state->v3 = v3;
682         state->v4 = v4;
683     }
684 
685     if (p < bEnd) {
686         XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
687         state->memsize = (unsigned)(bEnd-p);
688     }
689 
690     return XXH_OK;
691 }
692 
693 XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
694 {
695     XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
696 
697     if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
698         return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
699     else
700         return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
701 }
702 
703 
704 
705 FORCE_INLINE_TEMPLATE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
706 {
707     const BYTE * p = (const BYTE*)state->mem32;
708     const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize;
709     U32 h32;
710 
711     if (state->large_len) {
712         h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
713     } else {
714         h32 = state->v3 /* == seed */ + PRIME32_5;
715     }
716 
717     h32 += state->total_len_32;
718 
719     while (p+4<=bEnd) {
720         h32 += XXH_readLE32(p, endian) * PRIME32_3;
721         h32  = XXH_rotl32(h32, 17) * PRIME32_4;
722         p+=4;
723     }
724 
725     while (p<bEnd) {
726         h32 += (*p) * PRIME32_5;
727         h32  = XXH_rotl32(h32, 11) * PRIME32_1;
728         p++;
729     }
730 
731     h32 ^= h32 >> 15;
732     h32 *= PRIME32_2;
733     h32 ^= h32 >> 13;
734     h32 *= PRIME32_3;
735     h32 ^= h32 >> 16;
736 
737     return h32;
738 }
739 
740 
741 XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
742 {
743     XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
744 
745     if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
746         return XXH32_digest_endian(state_in, XXH_littleEndian);
747     else
748         return XXH32_digest_endian(state_in, XXH_bigEndian);
749 }
750 
751 
752 
753 /* **** XXH64 **** */
754 
755 FORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
756 {
757     const BYTE* p = (const BYTE*)input;
758     const BYTE* const bEnd = p + len;
759 
760 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
761     if (input==NULL) return XXH_ERROR;
762 #endif
763 
764     state->total_len += len;
765 
766     if (state->memsize + len < 32) {  /* fill in tmp buffer */
767         XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
768         state->memsize += (U32)len;
769         return XXH_OK;
770     }
771 
772     if (state->memsize) {   /* tmp buffer is full */
773         XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
774         state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));
775         state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));
776         state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));
777         state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));
778         p += 32-state->memsize;
779         state->memsize = 0;
780     }
781 
782     if (p+32 <= bEnd) {
783         const BYTE* const limit = bEnd - 32;
784         U64 v1 = state->v1;
785         U64 v2 = state->v2;
786         U64 v3 = state->v3;
787         U64 v4 = state->v4;
788 
789         do {
790             v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;
791             v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;
792             v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;
793             v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;
794         } while (p<=limit);
795 
796         state->v1 = v1;
797         state->v2 = v2;
798         state->v3 = v3;
799         state->v4 = v4;
800     }
801 
802     if (p < bEnd) {
803         XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
804         state->memsize = (unsigned)(bEnd-p);
805     }
806 
807     return XXH_OK;
808 }
809 
810 XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
811 {
812     XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
813 
814     if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
815         return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
816     else
817         return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
818 }
819 
820 
821 
822 FORCE_INLINE_TEMPLATE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
823 {
824     const BYTE * p = (const BYTE*)state->mem64;
825     const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize;
826     U64 h64;
827 
828     if (state->total_len >= 32) {
829         U64 const v1 = state->v1;
830         U64 const v2 = state->v2;
831         U64 const v3 = state->v3;
832         U64 const v4 = state->v4;
833 
834         h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
835         h64 = XXH64_mergeRound(h64, v1);
836         h64 = XXH64_mergeRound(h64, v2);
837         h64 = XXH64_mergeRound(h64, v3);
838         h64 = XXH64_mergeRound(h64, v4);
839     } else {
840         h64  = state->v3 + PRIME64_5;
841     }
842 
843     h64 += (U64) state->total_len;
844 
845     while (p+8<=bEnd) {
846         U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian));
847         h64 ^= k1;
848         h64  = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
849         p+=8;
850     }
851 
852     if (p+4<=bEnd) {
853         h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
854         h64  = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
855         p+=4;
856     }
857 
858     while (p<bEnd) {
859         h64 ^= (*p) * PRIME64_5;
860         h64  = XXH_rotl64(h64, 11) * PRIME64_1;
861         p++;
862     }
863 
864     h64 ^= h64 >> 33;
865     h64 *= PRIME64_2;
866     h64 ^= h64 >> 29;
867     h64 *= PRIME64_3;
868     h64 ^= h64 >> 32;
869 
870     return h64;
871 }
872 
873 
874 XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
875 {
876     XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
877 
878     if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
879         return XXH64_digest_endian(state_in, XXH_littleEndian);
880     else
881         return XXH64_digest_endian(state_in, XXH_bigEndian);
882 }
883 
884 
885 /* **************************
886 *  Canonical representation
887 ****************************/
888 
889 /*! Default XXH result types are basic unsigned 32 and 64 bits.
890 *   The canonical representation follows human-readable write convention, aka big-endian (large digits first).
891 *   These functions allow transformation of hash result into and from its canonical format.
892 *   This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs.
893 */
894 
895 XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
896 {
897     XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
898     if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
899     memcpy(dst, &hash, sizeof(*dst));
900 }
901 
902 XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
903 {
904     XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
905     if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
906     memcpy(dst, &hash, sizeof(*dst));
907 }
908 
909 XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
910 {
911     return XXH_readBE32(src);
912 }
913 
914 XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
915 {
916     return XXH_readBE64(src);
917 }
918