1 //  Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 /*
6 *  xxHash - Fast Hash algorithm
7 *  Copyright (C) 2012-2016, Yann Collet
8 *
9 *  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
10 *
11 *  Redistribution and use in source and binary forms, with or without
12 *  modification, are permitted provided that the following conditions are
13 *  met:
14 *
15 *  * Redistributions of source code must retain the above copyright
16 *  notice, this list of conditions and the following disclaimer.
17 *  * Redistributions in binary form must reproduce the above
18 *  copyright notice, this list of conditions and the following disclaimer
19 *  in the documentation and/or other materials provided with the
20 *  distribution.
21 *
22 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 *  You can contact the author at :
35 *  - xxHash homepage: http://www.xxhash.com
36 *  - xxHash source repository : https://github.com/Cyan4973/xxHash
37 */
38 
39 
40 /* since xxhash.c can be included (via XXH_INLINE_ALL),
41  * it's good practice to protect it with guard
42  * in case of multiples inclusions */
43 #ifndef XXHASH_C_01393879
44 #define XXHASH_C_01393879
45 
46 /* *************************************
47 *  Tuning parameters
48 ***************************************/
49 /*!XXH_FORCE_MEMORY_ACCESS :
50  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
51  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
52  * The below switch allow to select different access method for improved performance.
53  * Method 0 (default) : use `memcpy()`. Safe and portable.
54  * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
55  *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
56  * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.
57  *            It can generate buggy code on targets which do not support unaligned memory accesses.
58  *            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
59  * See http://stackoverflow.com/a/32095106/646947 for details.
60  * Prefer these methods in priority order (0 > 1 > 2)
61  */
62 #ifndef XXH_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */
63 #  if !defined(__clang__) && defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED) && defined(__ARM_ARCH) && (__ARM_ARCH == 6)
64 #    define XXH_FORCE_MEMORY_ACCESS 2
65 #  elif !defined(__clang__) && ((defined(__INTEL_COMPILER) && !defined(_WIN32)) || \
66   (defined(__GNUC__) && (defined(__ARM_ARCH) && __ARM_ARCH >= 7)))
67 #    define XXH_FORCE_MEMORY_ACCESS 1
68 #  endif
69 #endif
70 
71 /*!XXH_ACCEPT_NULL_INPUT_POINTER :
72  * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault.
73  * When this macro is enabled, xxHash actively checks input for null pointer.
74  * It it is, result for null input pointers is the same as a null-length input.
75  */
76 #ifndef XXH_ACCEPT_NULL_INPUT_POINTER   /* can be defined externally */
77 #  define XXH_ACCEPT_NULL_INPUT_POINTER 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;
84  * set it to 0 when the input is guaranteed to be aligned,
85  * or when alignment doesn't matter for performance.
86  */
87 #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
88 #  if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
89 #    define XXH_FORCE_ALIGN_CHECK 0
90 #  else
91 #    define XXH_FORCE_ALIGN_CHECK 1
92 #  endif
93 #endif
94 
95 /*!XXH_REROLL:
96  * Whether to reroll XXH32_finalize, and XXH64_finalize,
97  * instead of using an unrolled jump table/if statement loop.
98  *
99  * This is automatically defined on -Os/-Oz on GCC and Clang. */
100 #ifndef XXH_REROLL
101 #  if defined(__OPTIMIZE_SIZE__)
102 #    define XXH_REROLL 1
103 #  else
104 #    define XXH_REROLL 0
105 #  endif
106 #endif
107 
108 /* *************************************
109 *  Includes & Memory related functions
110 ***************************************/
111 /*! Modify the local functions below should you wish to use some other memory routines
112 *   for malloc(), free() */
113 #include <stdlib.h>
XXH_malloc(size_t s)114 static void* XXH_malloc(size_t s) { return malloc(s); }
XXH_free(void * p)115 static void  XXH_free  (void* p)  { free(p); }
116 /*! and for memcpy() */
117 #include <string.h>
XXH_memcpy(void * dest,const void * src,size_t size)118 static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
119 
120 #include <limits.h>   /* ULLONG_MAX */
121 
122 #ifndef XXH_STATIC_LINKING_ONLY
123 #define XXH_STATIC_LINKING_ONLY
124 #endif
125 
126 #include "xxhash.h"
127 
128 /* BEGIN RocksDB customizations */
129 #include "util/util.h" /* for FALLTHROUGH_INTENDED, inserted as appropriate */
130 /* END RocksDB customizations */
131 
132 /* *************************************
133 *  Compiler Specific Options
134 ***************************************/
135 #ifdef _MSC_VER    /* Visual Studio */
136 #  pragma warning(disable : 4127)      /* disable: C4127: conditional expression is constant */
137 #  define XXH_FORCE_INLINE static __forceinline
138 #  define XXH_NO_INLINE static __declspec(noinline)
139 #else
140 #  if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */
141 #    ifdef __GNUC__
142 #      define XXH_FORCE_INLINE static inline __attribute__((always_inline))
143 #      define XXH_NO_INLINE static __attribute__((noinline))
144 #    else
145 #      define XXH_FORCE_INLINE static inline
146 #      define XXH_NO_INLINE static
147 #    endif
148 #  else
149 #    define XXH_FORCE_INLINE static
150 #    define XXH_NO_INLINE static
151 #  endif /* __STDC_VERSION__ */
152 #endif
153 
154 
155 
156 /* *************************************
157 *  Debug
158 ***************************************/
159 /* DEBUGLEVEL is expected to be defined externally,
160  * typically through compiler command line.
161  * Value must be a number. */
162 #ifndef DEBUGLEVEL
163 #  define DEBUGLEVEL 0
164 #endif
165 
166 #if (DEBUGLEVEL>=1)
167 #  include <assert.h>   /* note : can still be disabled with NDEBUG */
168 #  define XXH_ASSERT(c)   assert(c)
169 #else
170 #  define XXH_ASSERT(c)   ((void)0)
171 #endif
172 
173 /* note : use after variable declarations */
174 #define XXH_STATIC_ASSERT(c)  { enum { XXH_sa = 1/(int)(!!(c)) }; }
175 
176 
177 /* *************************************
178 *  Basic Types
179 ***************************************/
180 #if !defined (__VMS) \
181  && (defined (__cplusplus) \
182  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
183 # include <stdint.h>
184   typedef uint8_t  xxh_u8;
185 #else
186   typedef unsigned char      xxh_u8;
187 #endif
188 typedef XXH32_hash_t xxh_u32;
189 
190 
191 /* ===   Memory access   === */
192 
193 #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
194 
195 /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
XXH_read32(const void * memPtr)196 static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; }
197 
198 #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
199 
200 /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
201 /* currently only defined for gcc and icc */
202 typedef union { xxh_u32 u32; } __attribute__((packed)) unalign;
XXH_read32(const void * ptr)203 static xxh_u32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
204 
205 #else
206 
207 /* portable and safe solution. Generally efficient.
208  * see : http://stackoverflow.com/a/32095106/646947
209  */
XXH_read32(const void * memPtr)210 static xxh_u32 XXH_read32(const void* memPtr)
211 {
212     xxh_u32 val;
213     memcpy(&val, memPtr, sizeof(val));
214     return val;
215 }
216 
217 #endif   /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
218 
219 
220 /* ===   Endianess   === */
221 typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
222 
223 /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
224 #ifndef XXH_CPU_LITTLE_ENDIAN
225 #  if defined(_WIN32) /* Windows is always little endian */ \
226      || defined(__LITTLE_ENDIAN__) \
227      || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
228 #    define XXH_CPU_LITTLE_ENDIAN 1
229 #  elif defined(__BIG_ENDIAN__) \
230      || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
231 #    define XXH_CPU_LITTLE_ENDIAN 0
232 #  else
XXH_isLittleEndian(void)233 static int XXH_isLittleEndian(void)
234 {
235     const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 };   /* don't use static : performance detrimental  */
236     return one.c[0];
237 }
238 #   define XXH_CPU_LITTLE_ENDIAN   XXH_isLittleEndian()
239 #  endif
240 #endif
241 
242 
243 
244 
245 /* ****************************************
246 *  Compiler-specific Functions and Macros
247 ******************************************/
248 #define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
249 
250 #ifndef __has_builtin
251 #  define __has_builtin(x) 0
252 #endif
253 
254 #if !defined(NO_CLANG_BUILTIN) && __has_builtin(__builtin_rotateleft32) && __has_builtin(__builtin_rotateleft64)
255 #  define XXH_rotl32 __builtin_rotateleft32
256 #  define XXH_rotl64 __builtin_rotateleft64
257 /* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
258 #elif defined(_MSC_VER)
259 #  define XXH_rotl32(x,r) _rotl(x,r)
260 #  define XXH_rotl64(x,r) _rotl64(x,r)
261 #else
262 #  define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
263 #  define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r))))
264 #endif
265 
266 #if defined(_MSC_VER)     /* Visual Studio */
267 #  define XXH_swap32 _byteswap_ulong
268 #elif XXH_GCC_VERSION >= 403
269 #  define XXH_swap32 __builtin_bswap32
270 #else
XXH_swap32(xxh_u32 x)271 static xxh_u32 XXH_swap32 (xxh_u32 x)
272 {
273     return  ((x << 24) & 0xff000000 ) |
274             ((x <<  8) & 0x00ff0000 ) |
275             ((x >>  8) & 0x0000ff00 ) |
276             ((x >> 24) & 0x000000ff );
277 }
278 #endif
279 
280 
281 /* ***************************
282 *  Memory reads
283 *****************************/
284 typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
285 
XXH_readLE32(const void * ptr)286 XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr)
287 {
288     return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
289 }
290 
XXH_readBE32(const void * ptr)291 static xxh_u32 XXH_readBE32(const void* ptr)
292 {
293     return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
294 }
295 
296 XXH_FORCE_INLINE xxh_u32
XXH_readLE32_align(const void * ptr,XXH_alignment align)297 XXH_readLE32_align(const void* ptr, XXH_alignment align)
298 {
299     if (align==XXH_unaligned) {
300         return XXH_readLE32(ptr);
301     } else {
302         return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr);
303     }
304 }
305 
306 
307 /* *************************************
308 *  Misc
309 ***************************************/
XXH_versionNumber(void)310 XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
311 
312 
313 /* *******************************************************************
314 *  32-bit hash functions
315 *********************************************************************/
316 static const xxh_u32 PRIME32_1 = 0x9E3779B1U;   /* 0b10011110001101110111100110110001 */
317 static const xxh_u32 PRIME32_2 = 0x85EBCA77U;   /* 0b10000101111010111100101001110111 */
318 static const xxh_u32 PRIME32_3 = 0xC2B2AE3DU;   /* 0b11000010101100101010111000111101 */
319 static const xxh_u32 PRIME32_4 = 0x27D4EB2FU;   /* 0b00100111110101001110101100101111 */
320 static const xxh_u32 PRIME32_5 = 0x165667B1U;   /* 0b00010110010101100110011110110001 */
321 
XXH32_round(xxh_u32 acc,xxh_u32 input)322 static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
323 {
324     acc += input * PRIME32_2;
325     acc  = XXH_rotl32(acc, 13);
326     acc *= PRIME32_1;
327 #if defined(__GNUC__) && defined(__SSE4_1__) && !defined(XXH_ENABLE_AUTOVECTORIZE)
328     /* UGLY HACK:
329      * This inline assembly hack forces acc into a normal register. This is the
330      * only thing that prevents GCC and Clang from autovectorizing the XXH32 loop
331      * (pragmas and attributes don't work for some resason) without globally
332      * disabling SSE4.1.
333      *
334      * The reason we want to avoid vectorization is because despite working on
335      * 4 integers at a time, there are multiple factors slowing XXH32 down on
336      * SSE4:
337      * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on newer chips!)
338      *   making it slightly slower to multiply four integers at once compared to four
339      *   integers independently. Even when pmulld was fastest, Sandy/Ivy Bridge, it is
340      *   still not worth it to go into SSE just to multiply unless doing a long operation.
341      *
342      * - Four instructions are required to rotate,
343      *      movqda tmp,  v // not required with VEX encoding
344      *      pslld  tmp, 13 // tmp <<= 13
345      *      psrld  v,   19 // x >>= 19
346      *      por    v,  tmp // x |= tmp
347      *   compared to one for scalar:
348      *      roll   v, 13    // reliably fast across the board
349      *      shldl  v, v, 13 // Sandy Bridge and later prefer this for some reason
350      *
351      * - Instruction level parallelism is actually more beneficial here because the
352      *   SIMD actually serializes this operation: While v1 is rotating, v2 can load data,
353      *   while v3 can multiply. SSE forces them to operate together.
354      *
355      * How this hack works:
356      * __asm__(""       // Declare an assembly block but don't declare any instructions
357      *          :       // However, as an Input/Output Operand,
358      *          "+r"    // constrain a read/write operand (+) as a general purpose register (r).
359      *          (acc)   // and set acc as the operand
360      * );
361      *
362      * Because of the 'r', the compiler has promised that seed will be in a
363      * general purpose register and the '+' says that it will be 'read/write',
364      * so it has to assume it has changed. It is like volatile without all the
365      * loads and stores.
366      *
367      * Since the argument has to be in a normal register (not an SSE register),
368      * each time XXH32_round is called, it is impossible to vectorize. */
369     __asm__("" : "+r" (acc));
370 #endif
371     return acc;
372 }
373 
374 /* mix all bits */
XXH32_avalanche(xxh_u32 h32)375 static xxh_u32 XXH32_avalanche(xxh_u32 h32)
376 {
377     h32 ^= h32 >> 15;
378     h32 *= PRIME32_2;
379     h32 ^= h32 >> 13;
380     h32 *= PRIME32_3;
381     h32 ^= h32 >> 16;
382     return(h32);
383 }
384 
385 #define XXH_get32bits(p) XXH_readLE32_align(p, align)
386 
387 static xxh_u32
XXH32_finalize(xxh_u32 h32,const xxh_u8 * ptr,size_t len,XXH_alignment align)388 XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
389 {
390 #define PROCESS1               \
391     h32 += (*ptr++) * PRIME32_5; \
392     h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
393 
394 #define PROCESS4                         \
395     h32 += XXH_get32bits(ptr) * PRIME32_3; \
396     ptr+=4;                                \
397     h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;
398 
399     /* Compact rerolled version */
400     if (XXH_REROLL) {
401         len &= 15;
402         while (len >= 4) {
403             PROCESS4;
404             len -= 4;
405         }
406         while (len > 0) {
407             PROCESS1;
408             --len;
409         }
410         return XXH32_avalanche(h32);
411     } else {
412          switch(len&15) /* or switch(bEnd - p) */ {
413            case 12:      PROCESS4;
414                          FALLTHROUGH_INTENDED;
415                          /* fallthrough */
416            case 8:       PROCESS4;
417                          FALLTHROUGH_INTENDED;
418                          /* fallthrough */
419            case 4:       PROCESS4;
420                          return XXH32_avalanche(h32);
421 
422            case 13:      PROCESS4;
423                          FALLTHROUGH_INTENDED;
424                          /* fallthrough */
425            case 9:       PROCESS4;
426                          FALLTHROUGH_INTENDED;
427                          /* fallthrough */
428            case 5:       PROCESS4;
429                          PROCESS1;
430                          return XXH32_avalanche(h32);
431 
432            case 14:      PROCESS4;
433                          FALLTHROUGH_INTENDED;
434                          /* fallthrough */
435            case 10:      PROCESS4;
436                          FALLTHROUGH_INTENDED;
437                          /* fallthrough */
438            case 6:       PROCESS4;
439                          PROCESS1;
440                          PROCESS1;
441                          return XXH32_avalanche(h32);
442 
443            case 15:      PROCESS4;
444                          FALLTHROUGH_INTENDED;
445                          /* fallthrough */
446            case 11:      PROCESS4;
447                          FALLTHROUGH_INTENDED;
448                          /* fallthrough */
449            case 7:       PROCESS4;
450                          FALLTHROUGH_INTENDED;
451                          /* fallthrough */
452            case 3:       PROCESS1;
453                          FALLTHROUGH_INTENDED;
454                          /* fallthrough */
455            case 2:       PROCESS1;
456                          FALLTHROUGH_INTENDED;
457                          /* fallthrough */
458            case 1:       PROCESS1;
459                          FALLTHROUGH_INTENDED;
460                          /* fallthrough */
461            case 0:       return XXH32_avalanche(h32);
462         }
463         XXH_ASSERT(0);
464         return h32;   /* reaching this point is deemed impossible */
465     }
466 }
467 
468 XXH_FORCE_INLINE xxh_u32
XXH32_endian_align(const xxh_u8 * input,size_t len,xxh_u32 seed,XXH_alignment align)469 XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align)
470 {
471     const xxh_u8* bEnd = input + len;
472     xxh_u32 h32;
473 
474 #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
475     if (input==NULL) {
476         len=0;
477         bEnd=input=(const xxh_u8*)(size_t)16;
478     }
479 #endif
480 
481     if (len>=16) {
482         const xxh_u8* const limit = bEnd - 15;
483         xxh_u32 v1 = seed + PRIME32_1 + PRIME32_2;
484         xxh_u32 v2 = seed + PRIME32_2;
485         xxh_u32 v3 = seed + 0;
486         xxh_u32 v4 = seed - PRIME32_1;
487 
488         do {
489             v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4;
490             v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4;
491             v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4;
492             v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4;
493         } while (input < limit);
494 
495         h32 = XXH_rotl32(v1, 1)  + XXH_rotl32(v2, 7)
496             + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
497     } else {
498         h32  = seed + PRIME32_5;
499     }
500 
501     h32 += (xxh_u32)len;
502 
503     return XXH32_finalize(h32, input, len&15, align);
504 }
505 
506 
XXH32(const void * input,size_t len,XXH32_hash_t seed)507 XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed)
508 {
509 #if 0
510     /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
511     XXH32_state_t state;
512     XXH32_reset(&state, seed);
513     XXH32_update(&state, (const xxh_u8*)input, len);
514     return XXH32_digest(&state);
515 
516 #else
517 
518     if (XXH_FORCE_ALIGN_CHECK) {
519         if ((((size_t)input) & 3) == 0) {   /* Input is 4-bytes aligned, leverage the speed benefit */
520             return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
521     }   }
522 
523     return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
524 #endif
525 }
526 
527 
528 
529 /*======   Hash streaming   ======*/
530 
XXH32_createState(void)531 XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
532 {
533     return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
534 }
XXH32_freeState(XXH32_state_t * statePtr)535 XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
536 {
537     XXH_free(statePtr);
538     return XXH_OK;
539 }
540 
XXH32_copyState(XXH32_state_t * dstState,const XXH32_state_t * srcState)541 XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
542 {
543     memcpy(dstState, srcState, sizeof(*dstState));
544 }
545 
XXH32_reset(XXH32_state_t * statePtr,XXH32_hash_t seed)546 XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed)
547 {
548     XXH32_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
549     memset(&state, 0, sizeof(state));
550     state.v1 = seed + PRIME32_1 + PRIME32_2;
551     state.v2 = seed + PRIME32_2;
552     state.v3 = seed + 0;
553     state.v4 = seed - PRIME32_1;
554     /* do not write into reserved, planned to be removed in a future version */
555     memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));
556     return XXH_OK;
557 }
558 
559 
560 XXH_PUBLIC_API XXH_errorcode
XXH32_update(XXH32_state_t * state,const void * input,size_t len)561 XXH32_update(XXH32_state_t* state, const void* input, size_t len)
562 {
563     if (input==NULL)
564 #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
565         return XXH_OK;
566 #else
567         return XXH_ERROR;
568 #endif
569 
570     {   const xxh_u8* p = (const xxh_u8*)input;
571         const xxh_u8* const bEnd = p + len;
572 
573         state->total_len_32 += (XXH32_hash_t)len;
574         state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16));
575 
576         if (state->memsize + len < 16)  {   /* fill in tmp buffer */
577             XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len);
578             state->memsize += (XXH32_hash_t)len;
579             return XXH_OK;
580         }
581 
582         if (state->memsize) {   /* some data left from previous update */
583             XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize);
584             {   const xxh_u32* p32 = state->mem32;
585                 state->v1 = XXH32_round(state->v1, XXH_readLE32(p32)); p32++;
586                 state->v2 = XXH32_round(state->v2, XXH_readLE32(p32)); p32++;
587                 state->v3 = XXH32_round(state->v3, XXH_readLE32(p32)); p32++;
588                 state->v4 = XXH32_round(state->v4, XXH_readLE32(p32));
589             }
590             p += 16-state->memsize;
591             state->memsize = 0;
592         }
593 
594         // uintptr_t casts added to avoid array-bounds error on
595         // some inlined calls
596         if ((uintptr_t)p <= (uintptr_t)bEnd - 16) {
597             const uintptr_t limit = (uintptr_t)bEnd - 16;
598             xxh_u32 v1 = state->v1;
599             xxh_u32 v2 = state->v2;
600             xxh_u32 v3 = state->v3;
601             xxh_u32 v4 = state->v4;
602 
603             do {
604                 v1 = XXH32_round(v1, XXH_readLE32(p)); p+=4;
605                 v2 = XXH32_round(v2, XXH_readLE32(p)); p+=4;
606                 v3 = XXH32_round(v3, XXH_readLE32(p)); p+=4;
607                 v4 = XXH32_round(v4, XXH_readLE32(p)); p+=4;
608             } while ((uintptr_t)p <= limit);
609 
610             state->v1 = v1;
611             state->v2 = v2;
612             state->v3 = v3;
613             state->v4 = v4;
614         }
615 
616         if (p < bEnd) {
617             XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
618             state->memsize = (unsigned)(bEnd-p);
619         }
620     }
621 
622     return XXH_OK;
623 }
624 
625 
XXH32_digest(const XXH32_state_t * state)626 XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* state)
627 {
628     xxh_u32 h32;
629 
630     if (state->large_len) {
631         h32 = XXH_rotl32(state->v1, 1)
632             + XXH_rotl32(state->v2, 7)
633             + XXH_rotl32(state->v3, 12)
634             + XXH_rotl32(state->v4, 18);
635     } else {
636         h32 = state->v3 /* == seed */ + PRIME32_5;
637     }
638 
639     h32 += state->total_len_32;
640 
641     return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned);
642 }
643 
644 
645 /*======   Canonical representation   ======*/
646 
647 /*! Default XXH result types are basic unsigned 32 and 64 bits.
648 *   The canonical representation follows human-readable write convention, aka big-endian (large digits first).
649 *   These functions allow transformation of hash result into and from its canonical format.
650 *   This way, hash values can be written into a file or buffer, remaining comparable across different systems.
651 */
652 
XXH32_canonicalFromHash(XXH32_canonical_t * dst,XXH32_hash_t hash)653 XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
654 {
655     XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
656     if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
657     memcpy(dst, &hash, sizeof(*dst));
658 }
659 
XXH32_hashFromCanonical(const XXH32_canonical_t * src)660 XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
661 {
662     return XXH_readBE32(src);
663 }
664 
665 
666 #ifndef XXH_NO_LONG_LONG
667 
668 /* *******************************************************************
669 *  64-bit hash functions
670 *********************************************************************/
671 
672 /*======   Memory access   ======*/
673 
674 typedef XXH64_hash_t xxh_u64;
675 
676 
677 /*! XXH_REROLL_XXH64:
678  * Whether to reroll the XXH64_finalize() loop.
679  *
680  * Just like XXH32, we can unroll the XXH64_finalize() loop. This can be a performance gain
681  * on 64-bit hosts, as only one jump is required.
682  *
683  * However, on 32-bit hosts, because arithmetic needs to be done with two 32-bit registers,
684  * and 64-bit arithmetic needs to be simulated, it isn't beneficial to unroll. The code becomes
685  * ridiculously large (the largest function in the binary on i386!), and rerolling it saves
686  * anywhere from 3kB to 20kB. It is also slightly faster because it fits into cache better
687  * and is more likely to be inlined by the compiler.
688  *
689  * If XXH_REROLL is defined, this is ignored and the loop is always rerolled. */
690 #ifndef XXH_REROLL_XXH64
691 #  if (defined(__ILP32__) || defined(_ILP32)) /* ILP32 is often defined on 32-bit GCC family */ \
692    || !(defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) /* x86-64 */ \
693      || defined(_M_ARM64) || defined(__aarch64__) || defined(__arm64__) /* aarch64 */ \
694      || defined(__PPC64__) || defined(__PPC64LE__) || defined(__ppc64__) || defined(__powerpc64__) /* ppc64 */ \
695      || defined(__mips64__) || defined(__mips64)) /* mips64 */ \
696    || (!defined(SIZE_MAX) || SIZE_MAX < ULLONG_MAX) /* check limits */
697 #    define XXH_REROLL_XXH64 1
698 #  else
699 #    define XXH_REROLL_XXH64 0
700 #  endif
701 #endif /* !defined(XXH_REROLL_XXH64) */
702 
703 #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
704 
705 /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
XXH_read64(const void * memPtr)706 static xxh_u64 XXH_read64(const void* memPtr) { return *(const xxh_u64*) memPtr; }
707 
708 #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
709 
710 /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
711 /* currently only defined for gcc and icc */
712 typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64;
XXH_read64(const void * ptr)713 static xxh_u64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; }
714 
715 #else
716 
717 /* portable and safe solution. Generally efficient.
718  * see : http://stackoverflow.com/a/32095106/646947
719  */
720 
XXH_read64(const void * memPtr)721 static xxh_u64 XXH_read64(const void* memPtr)
722 {
723     xxh_u64 val;
724     memcpy(&val, memPtr, sizeof(val));
725     return val;
726 }
727 
728 #endif   /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
729 
730 #if defined(_MSC_VER)     /* Visual Studio */
731 #  define XXH_swap64 _byteswap_uint64
732 #elif XXH_GCC_VERSION >= 403
733 #  define XXH_swap64 __builtin_bswap64
734 #else
XXH_swap64(xxh_u64 x)735 static xxh_u64 XXH_swap64 (xxh_u64 x)
736 {
737     return  ((x << 56) & 0xff00000000000000ULL) |
738             ((x << 40) & 0x00ff000000000000ULL) |
739             ((x << 24) & 0x0000ff0000000000ULL) |
740             ((x << 8)  & 0x000000ff00000000ULL) |
741             ((x >> 8)  & 0x00000000ff000000ULL) |
742             ((x >> 24) & 0x0000000000ff0000ULL) |
743             ((x >> 40) & 0x000000000000ff00ULL) |
744             ((x >> 56) & 0x00000000000000ffULL);
745 }
746 #endif
747 
XXH_readLE64(const void * ptr)748 XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* ptr)
749 {
750     return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
751 }
752 
XXH_readBE64(const void * ptr)753 static xxh_u64 XXH_readBE64(const void* ptr)
754 {
755     return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
756 }
757 
758 XXH_FORCE_INLINE xxh_u64
XXH_readLE64_align(const void * ptr,XXH_alignment align)759 XXH_readLE64_align(const void* ptr, XXH_alignment align)
760 {
761     if (align==XXH_unaligned)
762         return XXH_readLE64(ptr);
763     else
764         return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr);
765 }
766 
767 
768 /*======   xxh64   ======*/
769 
770 static const xxh_u64 PRIME64_1 = 0x9E3779B185EBCA87ULL;   /* 0b1001111000110111011110011011000110000101111010111100101010000111 */
771 static const xxh_u64 PRIME64_2 = 0xC2B2AE3D27D4EB4FULL;   /* 0b1100001010110010101011100011110100100111110101001110101101001111 */
772 static const xxh_u64 PRIME64_3 = 0x165667B19E3779F9ULL;   /* 0b0001011001010110011001111011000110011110001101110111100111111001 */
773 static const xxh_u64 PRIME64_4 = 0x85EBCA77C2B2AE63ULL;   /* 0b1000010111101011110010100111011111000010101100101010111001100011 */
774 static const xxh_u64 PRIME64_5 = 0x27D4EB2F165667C5ULL;   /* 0b0010011111010100111010110010111100010110010101100110011111000101 */
775 
XXH64_round(xxh_u64 acc,xxh_u64 input)776 static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input)
777 {
778     acc += input * PRIME64_2;
779     acc  = XXH_rotl64(acc, 31);
780     acc *= PRIME64_1;
781     return acc;
782 }
783 
XXH64_mergeRound(xxh_u64 acc,xxh_u64 val)784 static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val)
785 {
786     val  = XXH64_round(0, val);
787     acc ^= val;
788     acc  = acc * PRIME64_1 + PRIME64_4;
789     return acc;
790 }
791 
XXH64_avalanche(xxh_u64 h64)792 static xxh_u64 XXH64_avalanche(xxh_u64 h64)
793 {
794     h64 ^= h64 >> 33;
795     h64 *= PRIME64_2;
796     h64 ^= h64 >> 29;
797     h64 *= PRIME64_3;
798     h64 ^= h64 >> 32;
799     return h64;
800 }
801 
802 
803 #define XXH_get64bits(p) XXH_readLE64_align(p, align)
804 
805 static xxh_u64
XXH64_finalize(xxh_u64 h64,const xxh_u8 * ptr,size_t len,XXH_alignment align)806 XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align)
807 {
808 #define PROCESS1_64            \
809     h64 ^= (*ptr++) * PRIME64_5; \
810     h64 = XXH_rotl64(h64, 11) * PRIME64_1;
811 
812 #define PROCESS4_64          \
813     h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * PRIME64_1; \
814     ptr+=4;                    \
815     h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
816 
817 #define PROCESS8_64 {        \
818     xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr)); \
819     ptr+=8;                    \
820     h64 ^= k1;               \
821     h64  = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \
822 }
823 
824     /* Rerolled version for 32-bit targets is faster and much smaller. */
825     if (XXH_REROLL || XXH_REROLL_XXH64) {
826         len &= 31;
827         while (len >= 8) {
828             PROCESS8_64;
829             len -= 8;
830         }
831         if (len >= 4) {
832             PROCESS4_64;
833             len -= 4;
834         }
835         while (len > 0) {
836             PROCESS1_64;
837             --len;
838         }
839          return  XXH64_avalanche(h64);
840     } else {
841         switch(len & 31) {
842            case 24: PROCESS8_64;
843                     FALLTHROUGH_INTENDED;
844                          /* fallthrough */
845            case 16: PROCESS8_64;
846                     FALLTHROUGH_INTENDED;
847                          /* fallthrough */
848            case  8: PROCESS8_64;
849                     return XXH64_avalanche(h64);
850 
851            case 28: PROCESS8_64;
852                     FALLTHROUGH_INTENDED;
853                          /* fallthrough */
854            case 20: PROCESS8_64;
855                     FALLTHROUGH_INTENDED;
856                          /* fallthrough */
857            case 12: PROCESS8_64;
858                     FALLTHROUGH_INTENDED;
859                          /* fallthrough */
860            case  4: PROCESS4_64;
861                     return XXH64_avalanche(h64);
862 
863            case 25: PROCESS8_64;
864                     FALLTHROUGH_INTENDED;
865                          /* fallthrough */
866            case 17: PROCESS8_64;
867                     FALLTHROUGH_INTENDED;
868                          /* fallthrough */
869            case  9: PROCESS8_64;
870                     PROCESS1_64;
871                     return XXH64_avalanche(h64);
872 
873            case 29: PROCESS8_64;
874                     FALLTHROUGH_INTENDED;
875                          /* fallthrough */
876            case 21: PROCESS8_64;
877                     FALLTHROUGH_INTENDED;
878                          /* fallthrough */
879            case 13: PROCESS8_64;
880                     FALLTHROUGH_INTENDED;
881                          /* fallthrough */
882            case  5: PROCESS4_64;
883                     PROCESS1_64;
884                     return XXH64_avalanche(h64);
885 
886            case 26: PROCESS8_64;
887                     FALLTHROUGH_INTENDED;
888                          /* fallthrough */
889            case 18: PROCESS8_64;
890                     FALLTHROUGH_INTENDED;
891                          /* fallthrough */
892            case 10: PROCESS8_64;
893                     PROCESS1_64;
894                     PROCESS1_64;
895                     return XXH64_avalanche(h64);
896 
897            case 30: PROCESS8_64;
898                     FALLTHROUGH_INTENDED;
899                          /* fallthrough */
900            case 22: PROCESS8_64;
901                     FALLTHROUGH_INTENDED;
902                          /* fallthrough */
903            case 14: PROCESS8_64;
904                     FALLTHROUGH_INTENDED;
905                          /* fallthrough */
906            case  6: PROCESS4_64;
907                     PROCESS1_64;
908                     PROCESS1_64;
909                     return XXH64_avalanche(h64);
910 
911            case 27: PROCESS8_64;
912                     FALLTHROUGH_INTENDED;
913                          /* fallthrough */
914            case 19: PROCESS8_64;
915                     FALLTHROUGH_INTENDED;
916                          /* fallthrough */
917            case 11: PROCESS8_64;
918                     PROCESS1_64;
919                     PROCESS1_64;
920                     PROCESS1_64;
921                     return XXH64_avalanche(h64);
922 
923            case 31: PROCESS8_64;
924                     FALLTHROUGH_INTENDED;
925                          /* fallthrough */
926            case 23: PROCESS8_64;
927                     FALLTHROUGH_INTENDED;
928                          /* fallthrough */
929            case 15: PROCESS8_64;
930                     FALLTHROUGH_INTENDED;
931                          /* fallthrough */
932            case  7: PROCESS4_64;
933                     FALLTHROUGH_INTENDED;
934                          /* fallthrough */
935            case  3: PROCESS1_64;
936                     FALLTHROUGH_INTENDED;
937                          /* fallthrough */
938            case  2: PROCESS1_64;
939                     FALLTHROUGH_INTENDED;
940                          /* fallthrough */
941            case  1: PROCESS1_64;
942                     FALLTHROUGH_INTENDED;
943                          /* fallthrough */
944            case  0: return XXH64_avalanche(h64);
945         }
946     }
947     /* impossible to reach */
948     XXH_ASSERT(0);
949     return 0;  /* unreachable, but some compilers complain without it */
950 }
951 
952 XXH_FORCE_INLINE xxh_u64
XXH64_endian_align(const xxh_u8 * input,size_t len,xxh_u64 seed,XXH_alignment align)953 XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align)
954 {
955     const xxh_u8* bEnd = input + len;
956     xxh_u64 h64;
957 
958 #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
959     if (input==NULL) {
960         len=0;
961         bEnd=input=(const xxh_u8*)(size_t)32;
962     }
963 #endif
964 
965     if (len>=32) {
966         const xxh_u8* const limit = bEnd - 32;
967         xxh_u64 v1 = seed + PRIME64_1 + PRIME64_2;
968         xxh_u64 v2 = seed + PRIME64_2;
969         xxh_u64 v3 = seed + 0;
970         xxh_u64 v4 = seed - PRIME64_1;
971 
972         do {
973             v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8;
974             v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8;
975             v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8;
976             v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8;
977         } while (input<=limit);
978 
979         h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
980         h64 = XXH64_mergeRound(h64, v1);
981         h64 = XXH64_mergeRound(h64, v2);
982         h64 = XXH64_mergeRound(h64, v3);
983         h64 = XXH64_mergeRound(h64, v4);
984 
985     } else {
986         h64  = seed + PRIME64_5;
987     }
988 
989     h64 += (xxh_u64) len;
990 
991     return XXH64_finalize(h64, input, len, align);
992 }
993 
994 
XXH64(const void * input,size_t len,XXH64_hash_t seed)995 XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed)
996 {
997 #if 0
998     /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
999     XXH64_state_t state;
1000     XXH64_reset(&state, seed);
1001     XXH64_update(&state, (const xxh_u8*)input, len);
1002     return XXH64_digest(&state);
1003 
1004 #else
1005 
1006     if (XXH_FORCE_ALIGN_CHECK) {
1007         if ((((size_t)input) & 7)==0) {  /* Input is aligned, let's leverage the speed advantage */
1008             return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
1009     }   }
1010 
1011     return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
1012 
1013 #endif
1014 }
1015 
1016 /*======   Hash Streaming   ======*/
1017 
XXH64_createState(void)1018 XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
1019 {
1020     return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
1021 }
XXH64_freeState(XXH64_state_t * statePtr)1022 XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
1023 {
1024     XXH_free(statePtr);
1025     return XXH_OK;
1026 }
1027 
XXH64_copyState(XXH64_state_t * dstState,const XXH64_state_t * srcState)1028 XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
1029 {
1030     memcpy(dstState, srcState, sizeof(*dstState));
1031 }
1032 
XXH64_reset(XXH64_state_t * statePtr,XXH64_hash_t seed)1033 XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed)
1034 {
1035     XXH64_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
1036     memset(&state, 0, sizeof(state));
1037     state.v1 = seed + PRIME64_1 + PRIME64_2;
1038     state.v2 = seed + PRIME64_2;
1039     state.v3 = seed + 0;
1040     state.v4 = seed - PRIME64_1;
1041      /* do not write into reserved64, might be removed in a future version */
1042     memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved64));
1043     return XXH_OK;
1044 }
1045 
1046 XXH_PUBLIC_API XXH_errorcode
XXH64_update(XXH64_state_t * state,const void * input,size_t len)1047 XXH64_update (XXH64_state_t* state, const void* input, size_t len)
1048 {
1049     if (input==NULL)
1050 #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
1051         return XXH_OK;
1052 #else
1053         return XXH_ERROR;
1054 #endif
1055 
1056     {   const xxh_u8* p = (const xxh_u8*)input;
1057         const xxh_u8* const bEnd = p + len;
1058 
1059         state->total_len += len;
1060 
1061         if (state->memsize + len < 32) {  /* fill in tmp buffer */
1062             XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len);
1063             state->memsize += (xxh_u32)len;
1064             return XXH_OK;
1065         }
1066 
1067         if (state->memsize) {   /* tmp buffer is full */
1068             XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize);
1069             state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0));
1070             state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1));
1071             state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2));
1072             state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3));
1073             p += 32-state->memsize;
1074             state->memsize = 0;
1075         }
1076 
1077         // uintptr_t casts added to avoid array-bounds error on
1078         // some inlined calls
1079         if ((uintptr_t)p + 32 <= (uintptr_t)bEnd) {
1080             const uintptr_t limit = (uintptr_t)bEnd - 32;
1081             xxh_u64 v1 = state->v1;
1082             xxh_u64 v2 = state->v2;
1083             xxh_u64 v3 = state->v3;
1084             xxh_u64 v4 = state->v4;
1085 
1086             do {
1087                 v1 = XXH64_round(v1, XXH_readLE64(p)); p+=8;
1088                 v2 = XXH64_round(v2, XXH_readLE64(p)); p+=8;
1089                 v3 = XXH64_round(v3, XXH_readLE64(p)); p+=8;
1090                 v4 = XXH64_round(v4, XXH_readLE64(p)); p+=8;
1091             } while ((uintptr_t)p <= limit);
1092 
1093             state->v1 = v1;
1094             state->v2 = v2;
1095             state->v3 = v3;
1096             state->v4 = v4;
1097         }
1098 
1099         if (p < bEnd) {
1100             XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
1101             state->memsize = (unsigned)(bEnd-p);
1102         }
1103     }
1104 
1105     return XXH_OK;
1106 }
1107 
1108 
XXH64_digest(const XXH64_state_t * state)1109 XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* state)
1110 {
1111     xxh_u64 h64;
1112 
1113     if (state->total_len >= 32) {
1114         xxh_u64 const v1 = state->v1;
1115         xxh_u64 const v2 = state->v2;
1116         xxh_u64 const v3 = state->v3;
1117         xxh_u64 const v4 = state->v4;
1118 
1119         h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
1120         h64 = XXH64_mergeRound(h64, v1);
1121         h64 = XXH64_mergeRound(h64, v2);
1122         h64 = XXH64_mergeRound(h64, v3);
1123         h64 = XXH64_mergeRound(h64, v4);
1124     } else {
1125         h64  = state->v3 /*seed*/ + PRIME64_5;
1126     }
1127 
1128     h64 += (xxh_u64) state->total_len;
1129 
1130     return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned);
1131 }
1132 
1133 
1134 /*====== Canonical representation   ======*/
1135 
XXH64_canonicalFromHash(XXH64_canonical_t * dst,XXH64_hash_t hash)1136 XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
1137 {
1138     XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
1139     if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
1140     memcpy(dst, &hash, sizeof(*dst));
1141 }
1142 
XXH64_hashFromCanonical(const XXH64_canonical_t * src)1143 XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
1144 {
1145     return XXH_readBE64(src);
1146 }
1147 
1148 
1149 
1150 /* *********************************************************************
1151 *  XXH3
1152 *  New generation hash designed for speed on small keys and vectorization
1153 ************************************************************************ */
1154 
1155 #include "xxh3p.h" /* XXH3 preview for RocksDB */
1156 
1157 
1158 #endif  /* XXH_NO_LONG_LONG */
1159 
1160 #endif  /* XXHASH_C_01393879 */
1161