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