xxhash 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+