1262395Sbapt/*
2262395SbaptxxHash - Fast Hash algorithm
3262395SbaptCopyright (C) 2012-2013, Yann Collet.
4262395SbaptBSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
5262395Sbapt
6262395SbaptRedistribution and use in source and binary forms, with or without
7262395Sbaptmodification, are permitted provided that the following conditions are
8262395Sbaptmet:
9262395Sbapt
10262395Sbapt* Redistributions of source code must retain the above copyright
11262395Sbaptnotice, this list of conditions and the following disclaimer.
12262395Sbapt* Redistributions in binary form must reproduce the above
13262395Sbaptcopyright notice, this list of conditions and the following disclaimer
14262395Sbaptin the documentation and/or other materials provided with the
15262395Sbaptdistribution.
16262395Sbapt
17262395SbaptTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18262395Sbapt"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19262395SbaptLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20262395SbaptA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21262395SbaptOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22262395SbaptSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23262395SbaptLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24262395SbaptDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25262395SbaptTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26262395Sbapt(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27262395SbaptOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28262395Sbapt
29262395SbaptYou can contact the author at :
30262395Sbapt- xxHash source repository : http://code.google.com/p/xxhash/
31262395Sbapt*/
32262395Sbapt
33262395Sbapt
34262395Sbapt//**************************************
35262395Sbapt// Tuning parameters
36262395Sbapt//**************************************
37262395Sbapt// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
38262395Sbapt// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected.
39262395Sbapt// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance.
40262395Sbapt// You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32).
41262395Sbapt#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
42262395Sbapt#  define XXH_USE_UNALIGNED_ACCESS 1
43262395Sbapt#endif
44262395Sbapt
45262395Sbapt// XXH_ACCEPT_NULL_INPUT_POINTER :
46262395Sbapt// If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
47262395Sbapt// When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
48262395Sbapt// This option has a very small performance cost (only measurable on small inputs).
49262395Sbapt// By default, this option is disabled. To enable it, uncomment below define :
50262395Sbapt//#define XXH_ACCEPT_NULL_INPUT_POINTER 1
51262395Sbapt
52262395Sbapt// XXH_FORCE_NATIVE_FORMAT :
53262395Sbapt// By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
54262395Sbapt// Results are therefore identical for little-endian and big-endian CPU.
55262395Sbapt// This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
56262395Sbapt// Should endian-independance be of no importance for your application, you may set the #define below to 1.
57262395Sbapt// It will improve speed for Big-endian CPU.
58262395Sbapt// This option has no impact on Little_Endian CPU.
59262395Sbapt#define XXH_FORCE_NATIVE_FORMAT 0
60262395Sbapt
61262395Sbapt
62262395Sbapt//**************************************
63262395Sbapt// Compiler Specific Options
64262395Sbapt//**************************************
65262395Sbapt// Disable some Visual warning messages
66262395Sbapt#ifdef _MSC_VER  // Visual Studio
67262395Sbapt#  pragma warning(disable : 4127)      // disable: C4127: conditional expression is constant
68262395Sbapt#endif
69262395Sbapt
70262395Sbapt#ifdef _MSC_VER    // Visual Studio
71262395Sbapt#  define forceinline static __forceinline
72262395Sbapt#else
73262395Sbapt#  ifdef __GNUC__
74262395Sbapt#    define forceinline static inline __attribute__((always_inline))
75262395Sbapt#  else
76262395Sbapt#    define forceinline static inline
77262395Sbapt#  endif
78262395Sbapt#endif
79262395Sbapt
80262395Sbapt
81262395Sbapt//**************************************
82262395Sbapt// Includes & Memory related functions
83262395Sbapt//**************************************
84262395Sbapt#include "xxhash.h"
85262395Sbapt// Modify the local functions below should you wish to use some other memory related routines
86262395Sbapt// for malloc(), free()
87262395Sbapt#include <stdlib.h>
88262395Sbaptforceinline void* XXH_malloc(size_t s) { return malloc(s); }
89262395Sbaptforceinline void  XXH_free  (void* p)  { free(p); }
90262395Sbapt// for memcpy()
91262395Sbapt#include <string.h>
92262395Sbaptforceinline void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
93262395Sbapt
94262395Sbapt
95262395Sbapt//**************************************
96262395Sbapt// Basic Types
97262395Sbapt//**************************************
98262395Sbapt#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   // C99
99262395Sbapt# include <stdint.h>
100262395Sbapt  typedef uint8_t  BYTE;
101262395Sbapt  typedef uint16_t U16;
102262395Sbapt  typedef uint32_t U32;
103262395Sbapt  typedef  int32_t S32;
104262395Sbapt  typedef uint64_t U64;
105262395Sbapt#else
106262395Sbapt  typedef unsigned char      BYTE;
107262395Sbapt  typedef unsigned short     U16;
108262395Sbapt  typedef unsigned int       U32;
109262395Sbapt  typedef   signed int       S32;
110262395Sbapt  typedef unsigned long long U64;
111262395Sbapt#endif
112262395Sbapt
113262395Sbapt#if defined(__GNUC__)  && !defined(XXH_USE_UNALIGNED_ACCESS)
114262395Sbapt#  define _PACKED __attribute__ ((packed))
115262395Sbapt#else
116262395Sbapt#  define _PACKED
117262395Sbapt#endif
118262395Sbapt
119262395Sbapt#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
120262395Sbapt#  ifdef __IBMC__
121262395Sbapt#    pragma pack(1)
122262395Sbapt#  else
123262395Sbapt#    pragma pack(push, 1)
124262395Sbapt#  endif
125262395Sbapt#endif
126262395Sbapt
127262395Sbapttypedef struct _U32_S { U32 v; } _PACKED U32_S;
128262395Sbapt
129262395Sbapt#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
130262395Sbapt#  pragma pack(pop)
131262395Sbapt#endif
132262395Sbapt
133262395Sbapt#define A32(x) (((U32_S *)(x))->v)
134262395Sbapt
135262395Sbapt
136262395Sbapt//***************************************
137262395Sbapt// Compiler-specific Functions and Macros
138262395Sbapt//***************************************
139262395Sbapt#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
140262395Sbapt
141262395Sbapt// Note : although _rotl exists for minGW (GCC under windows), performance seems poor
142262395Sbapt#if defined(_MSC_VER)
143262395Sbapt#  define XXH_rotl32(x,r) _rotl(x,r)
144262395Sbapt#else
145262395Sbapt#  define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
146262395Sbapt#endif
147262395Sbapt
148262395Sbapt#if defined(_MSC_VER)     // Visual Studio
149262395Sbapt#  define XXH_swap32 _byteswap_ulong
150262395Sbapt#elif GCC_VERSION >= 403
151262395Sbapt#  define XXH_swap32 __builtin_bswap32
152262395Sbapt#else
153262395Sbaptstatic inline U32 XXH_swap32 (U32 x) {
154262395Sbapt    return  ((x << 24) & 0xff000000 ) |
155262395Sbapt        ((x <<  8) & 0x00ff0000 ) |
156262395Sbapt        ((x >>  8) & 0x0000ff00 ) |
157262395Sbapt        ((x >> 24) & 0x000000ff );}
158262395Sbapt#endif
159262395Sbapt
160262395Sbapt
161262395Sbapt//**************************************
162262395Sbapt// Constants
163262395Sbapt//**************************************
164262395Sbapt#define PRIME32_1   2654435761U
165262395Sbapt#define PRIME32_2   2246822519U
166262395Sbapt#define PRIME32_3   3266489917U
167262395Sbapt#define PRIME32_4    668265263U
168262395Sbapt#define PRIME32_5    374761393U
169262395Sbapt
170262395Sbapt
171262395Sbapt//**************************************
172262395Sbapt// Architecture Macros
173262395Sbapt//**************************************
174262395Sbapttypedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
175262395Sbapt#ifndef XXH_CPU_LITTLE_ENDIAN   // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch
176262395Sbapt    static const int one = 1;
177262395Sbapt#   define XXH_CPU_LITTLE_ENDIAN   (*(char*)(&one))
178262395Sbapt#endif
179262395Sbapt
180262395Sbapt
181262395Sbapt//**************************************
182262395Sbapt// Macros
183262395Sbapt//**************************************
184262395Sbapt#define XXH_STATIC_ASSERT(c)   { enum { XXH_static_assert = 1/(!!(c)) }; }    // use only *after* variable declarations
185262395Sbapt
186262395Sbapt
187262395Sbapt//****************************
188262395Sbapt// Memory reads
189262395Sbapt//****************************
190262395Sbapttypedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
191262395Sbapt
192262395Sbaptforceinline U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align)
193262395Sbapt{
194262395Sbapt    if (align==XXH_unaligned)
195262395Sbapt        return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
196262395Sbapt    else
197262395Sbapt        return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr);
198262395Sbapt}
199262395Sbapt
200262395Sbaptforceinline U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); }
201262395Sbapt
202262395Sbapt
203262395Sbapt//****************************
204262395Sbapt// Simple Hash Functions
205262395Sbapt//****************************
206262395Sbaptforceinline U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_endianess endian, XXH_alignment align)
207262395Sbapt{
208262395Sbapt    const BYTE* p = (const BYTE*)input;
209262395Sbapt    const BYTE* const bEnd = p + len;
210262395Sbapt    U32 h32;
211262395Sbapt
212262395Sbapt#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
213262395Sbapt    if (p==NULL) { len=0; p=(const BYTE*)(size_t)16; }
214262395Sbapt#endif
215262395Sbapt
216262395Sbapt    if (len>=16)
217262395Sbapt    {
218262395Sbapt        const BYTE* const limit = bEnd - 16;
219262395Sbapt        U32 v1 = seed + PRIME32_1 + PRIME32_2;
220262395Sbapt        U32 v2 = seed + PRIME32_2;
221262395Sbapt        U32 v3 = seed + 0;
222262395Sbapt        U32 v4 = seed - PRIME32_1;
223262395Sbapt
224262395Sbapt        do
225262395Sbapt        {
226262395Sbapt            v1 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
227262395Sbapt            v2 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
228262395Sbapt            v3 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
229262395Sbapt            v4 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
230262395Sbapt        } while (p<=limit);
231262395Sbapt
232262395Sbapt        h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
233262395Sbapt    }
234262395Sbapt    else
235262395Sbapt    {
236262395Sbapt        h32  = seed + PRIME32_5;
237262395Sbapt    }
238262395Sbapt
239262395Sbapt    h32 += (U32) len;
240262395Sbapt
241262395Sbapt    while (p<=bEnd-4)
242262395Sbapt    {
243262395Sbapt        h32 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_3;
244262395Sbapt        h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;
245262395Sbapt        p+=4;
246262395Sbapt    }
247262395Sbapt
248262395Sbapt    while (p<bEnd)
249262395Sbapt    {
250262395Sbapt        h32 += (*p) * PRIME32_5;
251262395Sbapt        h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
252262395Sbapt        p++;
253262395Sbapt    }
254262395Sbapt
255262395Sbapt    h32 ^= h32 >> 15;
256262395Sbapt    h32 *= PRIME32_2;
257262395Sbapt    h32 ^= h32 >> 13;
258262395Sbapt    h32 *= PRIME32_3;
259262395Sbapt    h32 ^= h32 >> 16;
260262395Sbapt
261262395Sbapt    return h32;
262262395Sbapt}
263262395Sbapt
264262395Sbapt
265262395SbaptU32 XXH32(const void* input, int len, U32 seed)
266262395Sbapt{
267262395Sbapt#if 0
268262395Sbapt    // Simple version, good for code maintenance, but unfortunately slow for small inputs
269262395Sbapt    void* state = XXH32_init(seed);
270262395Sbapt    XXH32_update(state, input, len);
271262395Sbapt    return XXH32_digest(state);
272262395Sbapt#else
273262395Sbapt    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
274262395Sbapt
275262395Sbapt#  if !defined(XXH_USE_UNALIGNED_ACCESS)
276262395Sbapt    if (!(((size_t)input) & 3))   // Input is aligned, let's leverage the speed advantage
277262395Sbapt    {
278262395Sbapt        if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
279262395Sbapt            return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
280262395Sbapt        else
281262395Sbapt            return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
282262395Sbapt    }
283262395Sbapt#  endif
284262395Sbapt
285262395Sbapt    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
286262395Sbapt        return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
287262395Sbapt    else
288262395Sbapt        return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
289262395Sbapt#endif
290262395Sbapt}
291262395Sbapt
292262395Sbapt
293262395Sbapt//****************************
294262395Sbapt// Advanced Hash Functions
295262395Sbapt//****************************
296262395Sbapt
297262395Sbaptstruct XXH_state32_t
298262395Sbapt{
299262395Sbapt    U64 total_len;
300262395Sbapt    U32 seed;
301262395Sbapt    U32 v1;
302262395Sbapt    U32 v2;
303262395Sbapt    U32 v3;
304262395Sbapt    U32 v4;
305262395Sbapt    int memsize;
306262395Sbapt    char memory[16];
307262395Sbapt};
308262395Sbapt
309262395Sbapt
310262395Sbaptint XXH32_sizeofState(void)
311262395Sbapt{
312262395Sbapt    XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t));   // A compilation error here means XXH32_SIZEOFSTATE is not large enough
313262395Sbapt    return sizeof(struct XXH_state32_t);
314262395Sbapt}
315262395Sbapt
316262395Sbapt
317262395SbaptXXH_errorcode XXH32_resetState(void* state_in, U32 seed)
318262395Sbapt{
319262395Sbapt    struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
320262395Sbapt    state->seed = seed;
321262395Sbapt    state->v1 = seed + PRIME32_1 + PRIME32_2;
322262395Sbapt    state->v2 = seed + PRIME32_2;
323262395Sbapt    state->v3 = seed + 0;
324262395Sbapt    state->v4 = seed - PRIME32_1;
325262395Sbapt    state->total_len = 0;
326262395Sbapt    state->memsize = 0;
327262395Sbapt    return XXH_OK;
328262395Sbapt}
329262395Sbapt
330262395Sbapt
331262395Sbaptvoid* XXH32_init (U32 seed)
332262395Sbapt{
333262395Sbapt    void* state = XXH_malloc (sizeof(struct XXH_state32_t));
334262395Sbapt    XXH32_resetState(state, seed);
335262395Sbapt    return state;
336262395Sbapt}
337262395Sbapt
338262395Sbapt
339262395Sbaptforceinline XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian)
340262395Sbapt{
341262395Sbapt    struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
342262395Sbapt    const BYTE* p = (const BYTE*)input;
343262395Sbapt    const BYTE* const bEnd = p + len;
344262395Sbapt
345262395Sbapt#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
346262395Sbapt    if (input==NULL) return XXH_ERROR;
347262395Sbapt#endif
348262395Sbapt
349262395Sbapt    state->total_len += len;
350262395Sbapt
351262395Sbapt    if (state->memsize + len < 16)   // fill in tmp buffer
352262395Sbapt    {
353262395Sbapt        XXH_memcpy(state->memory + state->memsize, input, len);
354262395Sbapt        state->memsize +=  len;
355262395Sbapt        return XXH_OK;
356262395Sbapt    }
357262395Sbapt
358262395Sbapt    if (state->memsize)   // some data left from previous update
359262395Sbapt    {
360262395Sbapt        XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize);
361262395Sbapt        {
362262395Sbapt            const U32* p32 = (const U32*)state->memory;
363262395Sbapt            state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;
364262395Sbapt            state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++;
365262395Sbapt            state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;
366262395Sbapt            state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;
367262395Sbapt        }
368262395Sbapt        p += 16-state->memsize;
369262395Sbapt        state->memsize = 0;
370262395Sbapt    }
371262395Sbapt
372262395Sbapt    if (p <= bEnd-16)
373262395Sbapt    {
374262395Sbapt        const BYTE* const limit = bEnd - 16;
375262395Sbapt        U32 v1 = state->v1;
376262395Sbapt        U32 v2 = state->v2;
377262395Sbapt        U32 v3 = state->v3;
378262395Sbapt        U32 v4 = state->v4;
379262395Sbapt
380262395Sbapt        do
381262395Sbapt        {
382262395Sbapt            v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
383262395Sbapt            v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
384262395Sbapt            v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
385262395Sbapt            v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
386262395Sbapt        } while (p<=limit);
387262395Sbapt
388262395Sbapt        state->v1 = v1;
389262395Sbapt        state->v2 = v2;
390262395Sbapt        state->v3 = v3;
391262395Sbapt        state->v4 = v4;
392262395Sbapt    }
393262395Sbapt
394262395Sbapt    if (p < bEnd)
395262395Sbapt    {
396262395Sbapt        XXH_memcpy(state->memory, p, bEnd-p);
397262395Sbapt        state->memsize = (int)(bEnd-p);
398262395Sbapt    }
399262395Sbapt
400262395Sbapt    return XXH_OK;
401262395Sbapt}
402262395Sbapt
403262395SbaptXXH_errorcode XXH32_update (void* state_in, const void* input, int len)
404262395Sbapt{
405262395Sbapt    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
406262395Sbapt
407262395Sbapt    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
408262395Sbapt        return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
409262395Sbapt    else
410262395Sbapt        return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
411262395Sbapt}
412262395Sbapt
413262395Sbapt
414262395Sbapt
415262395Sbaptforceinline U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian)
416262395Sbapt{
417262395Sbapt    struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
418262395Sbapt    const BYTE * p = (const BYTE*)state->memory;
419262395Sbapt    BYTE* bEnd = (BYTE*)state->memory + state->memsize;
420262395Sbapt    U32 h32;
421262395Sbapt
422262395Sbapt    if (state->total_len >= 16)
423262395Sbapt    {
424262395Sbapt        h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
425262395Sbapt    }
426262395Sbapt    else
427262395Sbapt    {
428262395Sbapt        h32  = state->seed + PRIME32_5;
429262395Sbapt    }
430262395Sbapt
431262395Sbapt    h32 += (U32) state->total_len;
432262395Sbapt
433262395Sbapt    while (p<=bEnd-4)
434262395Sbapt    {
435262395Sbapt        h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3;
436262395Sbapt        h32  = XXH_rotl32(h32, 17) * PRIME32_4;
437262395Sbapt        p+=4;
438262395Sbapt    }
439262395Sbapt
440262395Sbapt    while (p<bEnd)
441262395Sbapt    {
442262395Sbapt        h32 += (*p) * PRIME32_5;
443262395Sbapt        h32 = XXH_rotl32(h32, 11) * PRIME32_1;
444262395Sbapt        p++;
445262395Sbapt    }
446262395Sbapt
447262395Sbapt    h32 ^= h32 >> 15;
448262395Sbapt    h32 *= PRIME32_2;
449262395Sbapt    h32 ^= h32 >> 13;
450262395Sbapt    h32 *= PRIME32_3;
451262395Sbapt    h32 ^= h32 >> 16;
452262395Sbapt
453262395Sbapt    return h32;
454262395Sbapt}
455262395Sbapt
456262395Sbapt
457262395SbaptU32 XXH32_intermediateDigest (void* state_in)
458262395Sbapt{
459262395Sbapt    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
460262395Sbapt
461262395Sbapt    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
462262395Sbapt        return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian);
463262395Sbapt    else
464262395Sbapt        return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian);
465262395Sbapt}
466262395Sbapt
467262395Sbapt
468262395SbaptU32 XXH32_digest (void* state_in)
469262395Sbapt{
470262395Sbapt    U32 h32 = XXH32_intermediateDigest(state_in);
471262395Sbapt
472262395Sbapt    XXH_free(state_in);
473262395Sbapt
474262395Sbapt    return h32;
475262395Sbapt}
476