xxhash 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eb65711481aa5bbc9e1b7dc6c8338e0bda70f377
4
+ data.tar.gz: 5c4c2b5a262bd5831f9658aeccf35457a0556ce8
5
+ SHA512:
6
+ metadata.gz: a1160fe558a79aaa74a9fabe74e902890bcb7a7512ad08ff4634839fa40dfb2abe74eef367b689c5d42f178380a77deba6d7d6a8cd15ebf94d52a6600c4a7e85
7
+ data.tar.gz: 5615f46479f9c86b2af11dc36cea59abd1205ba2b06f0364c572bb5b54aa5a816d5f643619b5c0f43965fc9928763ea3c8b112a8134a391beee09a7d527f4d0a
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  *.gem
2
2
  *.rbc
3
3
  *.bundle
4
+ **/*.iml
4
5
  .config
5
6
  .yardoc
6
7
  Gemfile.lock
@@ -16,3 +17,4 @@ test/tmp
16
17
  test/version_tmp
17
18
  tmp
18
19
  lib/xxhash/xxhash.so
20
+ .idea/
@@ -1,3 +1,7 @@
1
+ ### master
2
+ * make seed param optional (by [@weakish](https://github.com/weakish))
3
+ * add 64-bit xxhash function (by [@justinwsmith](https://github.com/justinwsmith))
4
+
1
5
  ### 0.2.0 (September 4, 2013)
2
6
  * xxHash updated to [r32](https://code.google.com/p/xxhash/source/detail?r=32)
3
7
  * add `XXhash.xxh32_stream` method (by [@maltoe](https://github.com/maltoe))
data/Rakefile CHANGED
@@ -14,6 +14,7 @@ task :default => :test
14
14
 
15
15
  require 'rake/extensiontask'
16
16
  Rake::ExtensionTask.new('xxhash') do |ext|
17
+ # Customizations can be set here
17
18
  ext.lib_dir = 'lib/xxhash'
18
19
  end
19
20
 
@@ -1,8 +1,7 @@
1
1
  require 'mkmf'
2
2
 
3
- %w{g O3 Wall}.each do |flag|
4
- flag = "-#{flag}"
5
- $CPPFLAGS += " #{flag}" unless $CPPFLAGS.split.include? flag
3
+ %w{ g O3 Wno-padded }.each do |flag|
4
+ $CFLAGS += " -#{flag}"
6
5
  end
7
6
 
8
7
  create_makefile('xxhash/xxhash')
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  xxHash - Fast Hash algorithm
3
- Copyright (C) 2012-2013, Yann Collet.
3
+ Copyright (C) 2012-2014, Yann Collet.
4
4
  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
5
5
 
6
6
  Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
 
29
29
  You can contact the author at :
30
30
  - xxHash source repository : http://code.google.com/p/xxhash/
31
+ - public discussion board : https://groups.google.com/forum/#!forum/lz4c
31
32
  */
32
33
 
33
34
 
@@ -47,7 +48,7 @@ You can contact the author at :
47
48
  // When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
48
49
  // This option has a very small performance cost (only measurable on small inputs).
49
50
  // By default, this option is disabled. To enable it, uncomment below define :
50
- //#define XXH_ACCEPT_NULL_INPUT_POINTER 1
51
+ // #define XXH_ACCEPT_NULL_INPUT_POINTER 1
51
52
 
52
53
  // XXH_FORCE_NATIVE_FORMAT :
53
54
  // By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
@@ -58,7 +59,6 @@ You can contact the author at :
58
59
  // This option has no impact on Little_Endian CPU.
59
60
  #define XXH_FORCE_NATIVE_FORMAT 0
60
61
 
61
-
62
62
  //**************************************
63
63
  // Compiler Specific Options
64
64
  //**************************************
@@ -68,28 +68,30 @@ You can contact the author at :
68
68
  #endif
69
69
 
70
70
  #ifdef _MSC_VER // Visual Studio
71
- # define forceinline static __forceinline
71
+ # define FORCE_INLINE static __forceinline
72
72
  #else
73
73
  # ifdef __GNUC__
74
- # define forceinline static inline __attribute__((always_inline))
74
+ # define FORCE_INLINE static inline __attribute__((always_inline))
75
75
  # else
76
- # define forceinline static inline
76
+ # define FORCE_INLINE static inline
77
77
  # endif
78
78
  #endif
79
79
 
80
-
81
80
  //**************************************
82
81
  // Includes & Memory related functions
83
82
  //**************************************
84
83
  #include "libxxhash.h"
85
- // Modify the local functions below should you wish to use some other memory related routines
84
+ // Modify the local functions below should you wish to use some other memory routines
86
85
  // for malloc(), free()
87
86
  #include <stdlib.h>
88
- forceinline void* XXH_malloc(size_t s) { return malloc(s); }
89
- forceinline void XXH_free (void* p) { free(p); }
87
+ static void* XXH_malloc(size_t s) { return malloc(s); }
88
+ static void XXH_free (void* p) { free(p); }
90
89
  // for memcpy()
91
90
  #include <string.h>
92
- forceinline void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
91
+ static void* XXH_memcpy(void* dest, const void* src, size_t size)
92
+ {
93
+ return memcpy(dest,src,size);
94
+ }
93
95
 
94
96
 
95
97
  //**************************************
@@ -97,17 +99,17 @@ forceinline void* XXH_memcpy(void* dest, const void* src, size_t size) { return
97
99
  //**************************************
98
100
  #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
99
101
  # include <stdint.h>
100
- typedef uint8_t BYTE;
101
- typedef uint16_t U16;
102
- typedef uint32_t U32;
103
- typedef int32_t S32;
104
- typedef uint64_t U64;
102
+ typedef uint8_t BYTE;
103
+ typedef uint16_t U16;
104
+ typedef uint32_t U32;
105
+ typedef int32_t S32;
106
+ typedef uint64_t U64;
105
107
  #else
106
- typedef unsigned char BYTE;
107
- typedef unsigned short U16;
108
- typedef unsigned int U32;
109
- typedef signed int S32;
110
- typedef unsigned long long U64;
108
+ typedef unsigned char BYTE;
109
+ typedef unsigned short U16;
110
+ typedef unsigned int U32;
111
+ typedef signed int S32;
112
+ typedef unsigned long long U64;
111
113
  #endif
112
114
 
113
115
  #if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS)
@@ -124,13 +126,21 @@ forceinline void* XXH_memcpy(void* dest, const void* src, size_t size) { return
124
126
  # endif
125
127
  #endif
126
128
 
127
- typedef struct _U32_S { U32 v; } _PACKED U32_S;
129
+ typedef struct _U32_S
130
+ {
131
+ U32 v;
132
+ } _PACKED U32_S;
133
+ typedef struct _U64_S
134
+ {
135
+ U64 v;
136
+ } _PACKED U64_S;
128
137
 
129
138
  #if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
130
139
  # pragma pack(pop)
131
140
  #endif
132
141
 
133
142
  #define A32(x) (((U32_S *)(x))->v)
143
+ #define A64(x) (((U64_S *)(x))->v)
134
144
 
135
145
 
136
146
  //***************************************
@@ -141,20 +151,37 @@ typedef struct _U32_S { U32 v; } _PACKED U32_S;
141
151
  // Note : although _rotl exists for minGW (GCC under windows), performance seems poor
142
152
  #if defined(_MSC_VER)
143
153
  # define XXH_rotl32(x,r) _rotl(x,r)
154
+ # define XXH_rotl64(x,r) _rotl64(x,r)
144
155
  #else
145
156
  # define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
157
+ # define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
146
158
  #endif
147
159
 
148
160
  #if defined(_MSC_VER) // Visual Studio
149
161
  # define XXH_swap32 _byteswap_ulong
162
+ # define XXH_swap64 _byteswap_uint64
150
163
  #elif GCC_VERSION >= 403
151
164
  # define XXH_swap32 __builtin_bswap32
165
+ # define XXH_swap64 __builtin_bswap64
152
166
  #else
153
- static inline U32 XXH_swap32 (U32 x) {
167
+ static inline U32 XXH_swap32 (U32 x)
168
+ {
154
169
  return ((x << 24) & 0xff000000 ) |
155
- ((x << 8) & 0x00ff0000 ) |
156
- ((x >> 8) & 0x0000ff00 ) |
157
- ((x >> 24) & 0x000000ff );}
170
+ ((x << 8) & 0x00ff0000 ) |
171
+ ((x >> 8) & 0x0000ff00 ) |
172
+ ((x >> 24) & 0x000000ff );
173
+ }
174
+ static inline U64 XXH_swap64 (U64 x)
175
+ {
176
+ return ((x << 56) & 0xff00000000000000ULL) |
177
+ ((x << 40) & 0x00ff000000000000ULL) |
178
+ ((x << 24) & 0x0000ff0000000000ULL) |
179
+ ((x << 8) & 0x000000ff00000000ULL) |
180
+ ((x >> 8) & 0x00000000ff000000ULL) |
181
+ ((x >> 24) & 0x0000000000ff0000ULL) |
182
+ ((x >> 40) & 0x000000000000ff00ULL) |
183
+ ((x >> 56) & 0x00000000000000ffULL);
184
+ }
158
185
  #endif
159
186
 
160
187
 
@@ -167,13 +194,18 @@ static inline U32 XXH_swap32 (U32 x) {
167
194
  #define PRIME32_4 668265263U
168
195
  #define PRIME32_5 374761393U
169
196
 
197
+ #define PRIME64_1 11400714785074694791ULL
198
+ #define PRIME64_2 14029467366897019727ULL
199
+ #define PRIME64_3 1609587929392839161ULL
200
+ #define PRIME64_4 9650029242287828579ULL
201
+ #define PRIME64_5 2870177450012600261ULL
170
202
 
171
203
  //**************************************
172
204
  // Architecture Macros
173
205
  //**************************************
174
206
  typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
175
207
  #ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch
176
- static const int one = 1;
208
+ static const int one = 1;
177
209
  # define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one))
178
210
  #endif
179
211
 
@@ -189,28 +221,49 @@ typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
189
221
  //****************************
190
222
  typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
191
223
 
192
- forceinline U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align)
224
+ FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
193
225
  {
194
226
  if (align==XXH_unaligned)
195
227
  return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
196
228
  else
197
- return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr);
229
+ return endian==XXH_littleEndian ? *(U32*)ptr : XXH_swap32(*(U32*)ptr);
230
+ }
231
+
232
+ FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
233
+ {
234
+ return XXH_readLE32_align(ptr, endian, XXH_unaligned);
235
+ }
236
+
237
+ FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
238
+ {
239
+ if (align==XXH_unaligned)
240
+ return endian==XXH_littleEndian ? A64(ptr) : XXH_swap64(A64(ptr));
241
+ else
242
+ return endian==XXH_littleEndian ? *(U64*)ptr : XXH_swap64(*(U64*)ptr);
198
243
  }
199
244
 
200
- forceinline U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); }
245
+ FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
246
+ {
247
+ return XXH_readLE64_align(ptr, endian, XXH_unaligned);
248
+ }
201
249
 
202
250
 
203
251
  //****************************
204
252
  // Simple Hash Functions
205
253
  //****************************
206
- forceinline U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_endianess endian, XXH_alignment align)
254
+ FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
207
255
  {
208
256
  const BYTE* p = (const BYTE*)input;
209
- const BYTE* const bEnd = p + len;
257
+ const BYTE* bEnd = p + len;
210
258
  U32 h32;
259
+ #define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
211
260
 
212
261
  #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
213
- if (p==NULL) { len=0; p=(const BYTE*)(size_t)16; }
262
+ if (p==NULL)
263
+ {
264
+ len=0;
265
+ bEnd=p=(const BYTE*)(size_t)16;
266
+ }
214
267
  #endif
215
268
 
216
269
  if (len>=16)
@@ -223,11 +276,24 @@ forceinline U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_end
223
276
 
224
277
  do
225
278
  {
226
- v1 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
227
- v2 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
228
- v3 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
229
- v4 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
230
- } while (p<=limit);
279
+ v1 += XXH_get32bits(p) * PRIME32_2;
280
+ v1 = XXH_rotl32(v1, 13);
281
+ v1 *= PRIME32_1;
282
+ p+=4;
283
+ v2 += XXH_get32bits(p) * PRIME32_2;
284
+ v2 = XXH_rotl32(v2, 13);
285
+ v2 *= PRIME32_1;
286
+ p+=4;
287
+ v3 += XXH_get32bits(p) * PRIME32_2;
288
+ v3 = XXH_rotl32(v3, 13);
289
+ v3 *= PRIME32_1;
290
+ p+=4;
291
+ v4 += XXH_get32bits(p) * PRIME32_2;
292
+ v4 = XXH_rotl32(v4, 13);
293
+ v4 *= PRIME32_1;
294
+ p+=4;
295
+ }
296
+ while (p<=limit);
231
297
 
232
298
  h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
233
299
  }
@@ -238,9 +304,9 @@ forceinline U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_end
238
304
 
239
305
  h32 += (U32) len;
240
306
 
241
- while (p<=bEnd-4)
307
+ while (p+4<=bEnd)
242
308
  {
243
- h32 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_3;
309
+ h32 += XXH_get32bits(p) * PRIME32_3;
244
310
  h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
245
311
  p+=4;
246
312
  }
@@ -262,18 +328,19 @@ forceinline U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_end
262
328
  }
263
329
 
264
330
 
265
- U32 XXH32(const void* input, int len, U32 seed)
331
+ unsigned int XXH32 (const void* input, size_t len, unsigned seed)
266
332
  {
267
333
  #if 0
268
334
  // Simple version, good for code maintenance, but unfortunately slow for small inputs
269
- void* state = XXH32_init(seed);
270
- XXH32_update(state, input, len);
271
- return XXH32_digest(state);
335
+ XXH32_state_t state;
336
+ XXH32_reset(&state, seed);
337
+ XXH32_update(&state, input, len);
338
+ return XXH32_digest(&state);
272
339
  #else
273
340
  XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
274
341
 
275
342
  # if !defined(XXH_USE_UNALIGNED_ACCESS)
276
- if ((((size_t)input) & 3)) // Input is aligned, let's leverage the speed advantage
343
+ if ((((size_t)input) & 3) == 0) // Input is aligned, let's leverage the speed advantage
277
344
  {
278
345
  if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
279
346
  return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
@@ -289,12 +356,152 @@ U32 XXH32(const void* input, int len, U32 seed)
289
356
  #endif
290
357
  }
291
358
 
359
+ FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
360
+ {
361
+ const BYTE* p = (const BYTE*)input;
362
+ const BYTE* bEnd = p + len;
363
+ U64 h64;
364
+ #define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
292
365
 
293
- //****************************
294
- // Advanced Hash Functions
295
- //****************************
366
+ #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
367
+ if (p==NULL)
368
+ {
369
+ len=0;
370
+ bEnd=p=(const BYTE*)(size_t)32;
371
+ }
372
+ #endif
373
+
374
+ if (len>=32)
375
+ {
376
+ const BYTE* const limit = bEnd - 32;
377
+ U64 v1 = seed + PRIME64_1 + PRIME64_2;
378
+ U64 v2 = seed + PRIME64_2;
379
+ U64 v3 = seed + 0;
380
+ U64 v4 = seed - PRIME64_1;
381
+
382
+ do
383
+ {
384
+ v1 += XXH_get64bits(p) * PRIME64_2;
385
+ p+=8;
386
+ v1 = XXH_rotl64(v1, 31);
387
+ v1 *= PRIME64_1;
388
+ v2 += XXH_get64bits(p) * PRIME64_2;
389
+ p+=8;
390
+ v2 = XXH_rotl64(v2, 31);
391
+ v2 *= PRIME64_1;
392
+ v3 += XXH_get64bits(p) * PRIME64_2;
393
+ p+=8;
394
+ v3 = XXH_rotl64(v3, 31);
395
+ v3 *= PRIME64_1;
396
+ v4 += XXH_get64bits(p) * PRIME64_2;
397
+ p+=8;
398
+ v4 = XXH_rotl64(v4, 31);
399
+ v4 *= PRIME64_1;
400
+ }
401
+ while (p<=limit);
402
+
403
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
404
+
405
+ v1 *= PRIME64_2;
406
+ v1 = XXH_rotl64(v1, 31);
407
+ v1 *= PRIME64_1;
408
+ h64 ^= v1;
409
+ h64 = h64 * PRIME64_1 + PRIME64_4;
410
+
411
+ v2 *= PRIME64_2;
412
+ v2 = XXH_rotl64(v2, 31);
413
+ v2 *= PRIME64_1;
414
+ h64 ^= v2;
415
+ h64 = h64 * PRIME64_1 + PRIME64_4;
416
+
417
+ v3 *= PRIME64_2;
418
+ v3 = XXH_rotl64(v3, 31);
419
+ v3 *= PRIME64_1;
420
+ h64 ^= v3;
421
+ h64 = h64 * PRIME64_1 + PRIME64_4;
422
+
423
+ v4 *= PRIME64_2;
424
+ v4 = XXH_rotl64(v4, 31);
425
+ v4 *= PRIME64_1;
426
+ h64 ^= v4;
427
+ h64 = h64 * PRIME64_1 + PRIME64_4;
428
+ }
429
+ else
430
+ {
431
+ h64 = seed + PRIME64_5;
432
+ }
433
+
434
+ h64 += (U64) len;
435
+
436
+ while (p+8<=bEnd)
437
+ {
438
+ U64 k1 = XXH_get64bits(p);
439
+ k1 *= PRIME64_2;
440
+ k1 = XXH_rotl64(k1,31);
441
+ k1 *= PRIME64_1;
442
+ h64 ^= k1;
443
+ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
444
+ p+=8;
445
+ }
446
+
447
+ if (p+4<=bEnd)
448
+ {
449
+ h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
450
+ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
451
+ p+=4;
452
+ }
453
+
454
+ while (p<bEnd)
455
+ {
456
+ h64 ^= (*p) * PRIME64_5;
457
+ h64 = XXH_rotl64(h64, 11) * PRIME64_1;
458
+ p++;
459
+ }
460
+
461
+ h64 ^= h64 >> 33;
462
+ h64 *= PRIME64_2;
463
+ h64 ^= h64 >> 29;
464
+ h64 *= PRIME64_3;
465
+ h64 ^= h64 >> 32;
466
+
467
+ return h64;
468
+ }
469
+
470
+
471
+ unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
472
+ {
473
+ #if 0
474
+ // Simple version, good for code maintenance, but unfortunately slow for small inputs
475
+ XXH64_state_t state;
476
+ XXH64_reset(&state, seed);
477
+ XXH64_update(&state, input, len);
478
+ return XXH64_digest(&state);
479
+ #else
480
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
481
+
482
+ # if !defined(XXH_USE_UNALIGNED_ACCESS)
483
+ if ((((size_t)input) & 7)==0) // Input is aligned, let's leverage the speed advantage
484
+ {
485
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
486
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
487
+ else
488
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
489
+ }
490
+ # endif
491
+
492
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
493
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
494
+ else
495
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
496
+ #endif
497
+ }
296
498
 
297
- struct XXH_state32_t
499
+ /****************************************************
500
+ * Advanced Hash Functions
501
+ ****************************************************/
502
+
503
+ /*** Allocation ***/
504
+ typedef struct
298
505
  {
299
506
  U64 total_len;
300
507
  U32 seed;
@@ -302,21 +509,51 @@ struct XXH_state32_t
302
509
  U32 v2;
303
510
  U32 v3;
304
511
  U32 v4;
305
- int memsize;
306
- char memory[16];
307
- };
512
+ U32 mem32[4]; /* defined as U32 for alignment */
513
+ U32 memsize;
514
+ } XXH_istate32_t;
515
+
516
+ typedef struct
517
+ {
518
+ U64 total_len;
519
+ U64 seed;
520
+ U64 v1;
521
+ U64 v2;
522
+ U64 v3;
523
+ U64 v4;
524
+ U64 mem64[4]; /* defined as U64 for alignment */
525
+ U32 memsize;
526
+ } XXH_istate64_t;
308
527
 
309
528
 
310
- int XXH32_sizeofState()
529
+ XXH32_state_t* XXH32_createState(void)
530
+ {
531
+ XXH_STATIC_ASSERT(sizeof(XXH32_state_t) >= sizeof(XXH_istate32_t)); // A compilation error here means XXH32_state_t is not large enough
532
+ return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
533
+ }
534
+ XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
535
+ {
536
+ XXH_free(statePtr);
537
+ return XXH_OK;
538
+ }
539
+
540
+ XXH64_state_t* XXH64_createState(void)
541
+ {
542
+ XXH_STATIC_ASSERT(sizeof(XXH64_state_t) >= sizeof(XXH_istate64_t)); // A compilation error here means XXH64_state_t is not large enough
543
+ return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
544
+ }
545
+ XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
311
546
  {
312
- XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t)); // A compilation error here means XXH32_SIZEOFSTATE is not large enough
313
- return sizeof(struct XXH_state32_t);
547
+ XXH_free(statePtr);
548
+ return XXH_OK;
314
549
  }
315
550
 
316
551
 
317
- XXH_errorcode XXH32_resetState(void* state_in, U32 seed)
552
+ /*** Hash feed ***/
553
+
554
+ XXH_errorcode XXH32_reset(XXH32_state_t* state_in, U32 seed)
318
555
  {
319
- struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
556
+ XXH_istate32_t* state = (XXH_istate32_t*) state_in;
320
557
  state->seed = seed;
321
558
  state->v1 = seed + PRIME32_1 + PRIME32_2;
322
559
  state->v2 = seed + PRIME32_2;
@@ -327,18 +564,23 @@ XXH_errorcode XXH32_resetState(void* state_in, U32 seed)
327
564
  return XXH_OK;
328
565
  }
329
566
 
330
-
331
- void* XXH32_init (U32 seed)
567
+ XXH_errorcode XXH64_reset(XXH64_state_t* state_in, unsigned long long seed)
332
568
  {
333
- void* state = XXH_malloc (sizeof(struct XXH_state32_t));
334
- XXH32_resetState(state, seed);
335
- return state;
569
+ XXH_istate64_t* state = (XXH_istate64_t*) state_in;
570
+ state->seed = seed;
571
+ state->v1 = seed + PRIME64_1 + PRIME64_2;
572
+ state->v2 = seed + PRIME64_2;
573
+ state->v3 = seed + 0;
574
+ state->v4 = seed - PRIME64_1;
575
+ state->total_len = 0;
576
+ state->memsize = 0;
577
+ return XXH_OK;
336
578
  }
337
579
 
338
580
 
339
- forceinline XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian)
581
+ FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state_in, const void* input, size_t len, XXH_endianess endian)
340
582
  {
341
- struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
583
+ XXH_istate32_t* state = (XXH_istate32_t *) state_in;
342
584
  const BYTE* p = (const BYTE*)input;
343
585
  const BYTE* const bEnd = p + len;
344
586
 
@@ -350,20 +592,32 @@ forceinline XXH_errorcode XXH32_update_endian (void* state_in, const void* input
350
592
 
351
593
  if (state->memsize + len < 16) // fill in tmp buffer
352
594
  {
353
- XXH_memcpy(state->memory + state->memsize, input, len);
354
- state->memsize += len;
595
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
596
+ state->memsize += (U32)len;
355
597
  return XXH_OK;
356
598
  }
357
599
 
358
600
  if (state->memsize) // some data left from previous update
359
601
  {
360
- XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize);
602
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
361
603
  {
362
- const U32* p32 = (const U32*)state->memory;
363
- state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;
364
- state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++;
365
- state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;
366
- state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;
604
+ const U32* p32 = state->mem32;
605
+ state->v1 += XXH_readLE32(p32, endian) * PRIME32_2;
606
+ state->v1 = XXH_rotl32(state->v1, 13);
607
+ state->v1 *= PRIME32_1;
608
+ p32++;
609
+ state->v2 += XXH_readLE32(p32, endian) * PRIME32_2;
610
+ state->v2 = XXH_rotl32(state->v2, 13);
611
+ state->v2 *= PRIME32_1;
612
+ p32++;
613
+ state->v3 += XXH_readLE32(p32, endian) * PRIME32_2;
614
+ state->v3 = XXH_rotl32(state->v3, 13);
615
+ state->v3 *= PRIME32_1;
616
+ p32++;
617
+ state->v4 += XXH_readLE32(p32, endian) * PRIME32_2;
618
+ state->v4 = XXH_rotl32(state->v4, 13);
619
+ state->v4 *= PRIME32_1;
620
+ p32++;
367
621
  }
368
622
  p += 16-state->memsize;
369
623
  state->memsize = 0;
@@ -379,11 +633,24 @@ forceinline XXH_errorcode XXH32_update_endian (void* state_in, const void* input
379
633
 
380
634
  do
381
635
  {
382
- v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
383
- v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
384
- v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
385
- v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
386
- } while (p<=limit);
636
+ v1 += XXH_readLE32(p, endian) * PRIME32_2;
637
+ v1 = XXH_rotl32(v1, 13);
638
+ v1 *= PRIME32_1;
639
+ p+=4;
640
+ v2 += XXH_readLE32(p, endian) * PRIME32_2;
641
+ v2 = XXH_rotl32(v2, 13);
642
+ v2 *= PRIME32_1;
643
+ p+=4;
644
+ v3 += XXH_readLE32(p, endian) * PRIME32_2;
645
+ v3 = XXH_rotl32(v3, 13);
646
+ v3 *= PRIME32_1;
647
+ p+=4;
648
+ v4 += XXH_readLE32(p, endian) * PRIME32_2;
649
+ v4 = XXH_rotl32(v4, 13);
650
+ v4 *= PRIME32_1;
651
+ p+=4;
652
+ }
653
+ while (p<=limit);
387
654
 
388
655
  state->v1 = v1;
389
656
  state->v2 = v2;
@@ -393,14 +660,14 @@ forceinline XXH_errorcode XXH32_update_endian (void* state_in, const void* input
393
660
 
394
661
  if (p < bEnd)
395
662
  {
396
- XXH_memcpy(state->memory, p, bEnd-p);
397
- state->memsize = (int)(bEnd-p);
663
+ XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
664
+ state->memsize = (U32)(bEnd-p);
398
665
  }
399
666
 
400
667
  return XXH_OK;
401
668
  }
402
669
 
403
- XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
670
+ XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
404
671
  {
405
672
  XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
406
673
 
@@ -412,11 +679,11 @@ XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
412
679
 
413
680
 
414
681
 
415
- forceinline U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian)
682
+ FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state_in, XXH_endianess endian)
416
683
  {
417
- struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
418
- const BYTE * p = (const BYTE*)state->memory;
419
- BYTE* bEnd = (BYTE*)state->memory + state->memsize;
684
+ XXH_istate32_t* state = (XXH_istate32_t*) state_in;
685
+ const BYTE * p = (const BYTE*)state->mem32;
686
+ BYTE* bEnd = (BYTE*)(state->mem32) + state->memsize;
420
687
  U32 h32;
421
688
 
422
689
  if (state->total_len >= 16)
@@ -430,9 +697,9 @@ forceinline U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess e
430
697
 
431
698
  h32 += (U32) state->total_len;
432
699
 
433
- while (p<=bEnd-4)
700
+ while (p+4<=bEnd)
434
701
  {
435
- h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3;
702
+ h32 += XXH_readLE32(p, endian) * PRIME32_3;
436
703
  h32 = XXH_rotl32(h32, 17) * PRIME32_4;
437
704
  p+=4;
438
705
  }
@@ -454,22 +721,207 @@ forceinline U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess e
454
721
  }
455
722
 
456
723
 
457
- U32 XXH32_intermediateDigest (void* state_in)
724
+ U32 XXH32_digest (const XXH32_state_t* state_in)
458
725
  {
459
726
  XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
460
727
 
461
728
  if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
462
- return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian);
729
+ return XXH32_digest_endian(state_in, XXH_littleEndian);
463
730
  else
464
- return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian);
731
+ return XXH32_digest_endian(state_in, XXH_bigEndian);
465
732
  }
466
733
 
467
734
 
468
- U32 XXH32_digest (void* state_in)
735
+ FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state_in, const void* input, size_t len, XXH_endianess endian)
469
736
  {
470
- U32 h32 = XXH32_intermediateDigest(state_in);
737
+ XXH_istate64_t * state = (XXH_istate64_t *) state_in;
738
+ const BYTE* p = (const BYTE*)input;
739
+ const BYTE* const bEnd = p + len;
471
740
 
472
- XXH_free(state_in);
741
+ #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
742
+ if (input==NULL) return XXH_ERROR;
743
+ #endif
473
744
 
474
- return h32;
745
+ state->total_len += len;
746
+
747
+ if (state->memsize + len < 32) // fill in tmp buffer
748
+ {
749
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
750
+ state->memsize += (U32)len;
751
+ return XXH_OK;
752
+ }
753
+
754
+ if (state->memsize) // some data left from previous update
755
+ {
756
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
757
+ {
758
+ const U64* p64 = state->mem64;
759
+ state->v1 += XXH_readLE64(p64, endian) * PRIME64_2;
760
+ state->v1 = XXH_rotl64(state->v1, 31);
761
+ state->v1 *= PRIME64_1;
762
+ p64++;
763
+ state->v2 += XXH_readLE64(p64, endian) * PRIME64_2;
764
+ state->v2 = XXH_rotl64(state->v2, 31);
765
+ state->v2 *= PRIME64_1;
766
+ p64++;
767
+ state->v3 += XXH_readLE64(p64, endian) * PRIME64_2;
768
+ state->v3 = XXH_rotl64(state->v3, 31);
769
+ state->v3 *= PRIME64_1;
770
+ p64++;
771
+ state->v4 += XXH_readLE64(p64, endian) * PRIME64_2;
772
+ state->v4 = XXH_rotl64(state->v4, 31);
773
+ state->v4 *= PRIME64_1;
774
+ p64++;
775
+ }
776
+ p += 32-state->memsize;
777
+ state->memsize = 0;
778
+ }
779
+
780
+ if (p+32 <= bEnd)
781
+ {
782
+ const BYTE* const limit = bEnd - 32;
783
+ U64 v1 = state->v1;
784
+ U64 v2 = state->v2;
785
+ U64 v3 = state->v3;
786
+ U64 v4 = state->v4;
787
+
788
+ do
789
+ {
790
+ v1 += XXH_readLE64(p, endian) * PRIME64_2;
791
+ v1 = XXH_rotl64(v1, 31);
792
+ v1 *= PRIME64_1;
793
+ p+=8;
794
+ v2 += XXH_readLE64(p, endian) * PRIME64_2;
795
+ v2 = XXH_rotl64(v2, 31);
796
+ v2 *= PRIME64_1;
797
+ p+=8;
798
+ v3 += XXH_readLE64(p, endian) * PRIME64_2;
799
+ v3 = XXH_rotl64(v3, 31);
800
+ v3 *= PRIME64_1;
801
+ p+=8;
802
+ v4 += XXH_readLE64(p, endian) * PRIME64_2;
803
+ v4 = XXH_rotl64(v4, 31);
804
+ v4 *= PRIME64_1;
805
+ p+=8;
806
+ }
807
+ while (p<=limit);
808
+
809
+ state->v1 = v1;
810
+ state->v2 = v2;
811
+ state->v3 = v3;
812
+ state->v4 = v4;
813
+ }
814
+
815
+ if (p < bEnd)
816
+ {
817
+ XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
818
+ state->memsize = (U32)(bEnd-p);
819
+ }
820
+
821
+ return XXH_OK;
822
+ }
823
+
824
+ XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
825
+ {
826
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
827
+
828
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
829
+ return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
830
+ else
831
+ return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
832
+ }
833
+
834
+
835
+
836
+ FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state_in, XXH_endianess endian)
837
+ {
838
+ XXH_istate64_t * state = (XXH_istate64_t *) state_in;
839
+ const BYTE * p = (const BYTE*)state->mem64;
840
+ BYTE* bEnd = (BYTE*)state->mem64 + state->memsize;
841
+ U64 h64;
842
+
843
+ if (state->total_len >= 32)
844
+ {
845
+ U64 v1 = state->v1;
846
+ U64 v2 = state->v2;
847
+ U64 v3 = state->v3;
848
+ U64 v4 = state->v4;
849
+
850
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
851
+
852
+ v1 *= PRIME64_2;
853
+ v1 = XXH_rotl64(v1, 31);
854
+ v1 *= PRIME64_1;
855
+ h64 ^= v1;
856
+ h64 = h64*PRIME64_1 + PRIME64_4;
857
+
858
+ v2 *= PRIME64_2;
859
+ v2 = XXH_rotl64(v2, 31);
860
+ v2 *= PRIME64_1;
861
+ h64 ^= v2;
862
+ h64 = h64*PRIME64_1 + PRIME64_4;
863
+
864
+ v3 *= PRIME64_2;
865
+ v3 = XXH_rotl64(v3, 31);
866
+ v3 *= PRIME64_1;
867
+ h64 ^= v3;
868
+ h64 = h64*PRIME64_1 + PRIME64_4;
869
+
870
+ v4 *= PRIME64_2;
871
+ v4 = XXH_rotl64(v4, 31);
872
+ v4 *= PRIME64_1;
873
+ h64 ^= v4;
874
+ h64 = h64*PRIME64_1 + PRIME64_4;
875
+ }
876
+ else
877
+ {
878
+ h64 = state->seed + PRIME64_5;
879
+ }
880
+
881
+ h64 += (U64) state->total_len;
882
+
883
+ while (p+8<=bEnd)
884
+ {
885
+ U64 k1 = XXH_readLE64(p, endian);
886
+ k1 *= PRIME64_2;
887
+ k1 = XXH_rotl64(k1,31);
888
+ k1 *= PRIME64_1;
889
+ h64 ^= k1;
890
+ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
891
+ p+=8;
892
+ }
893
+
894
+ if (p+4<=bEnd)
895
+ {
896
+ h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
897
+ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
898
+ p+=4;
899
+ }
900
+
901
+ while (p<bEnd)
902
+ {
903
+ h64 ^= (*p) * PRIME64_5;
904
+ h64 = XXH_rotl64(h64, 11) * PRIME64_1;
905
+ p++;
906
+ }
907
+
908
+ h64 ^= h64 >> 33;
909
+ h64 *= PRIME64_2;
910
+ h64 ^= h64 >> 29;
911
+ h64 *= PRIME64_3;
912
+ h64 ^= h64 >> 32;
913
+
914
+ return h64;
475
915
  }
916
+
917
+
918
+ unsigned long long XXH64_digest (const XXH64_state_t* state_in)
919
+ {
920
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
921
+
922
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
923
+ return XXH64_digest_endian(state_in, XXH_littleEndian);
924
+ else
925
+ return XXH64_digest_endian(state_in, XXH_bigEndian);
926
+ }
927
+