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