zstd-ruby 1.3.5.0 → 1.3.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -2
  3. data/README.md +2 -1
  4. data/ext/zstdruby/libzstd/BUCK +1 -0
  5. data/ext/zstdruby/libzstd/Makefile +25 -13
  6. data/ext/zstdruby/libzstd/README.md +11 -10
  7. data/ext/zstdruby/libzstd/common/bitstream.h +8 -11
  8. data/ext/zstdruby/libzstd/common/compiler.h +30 -8
  9. data/ext/zstdruby/libzstd/common/cpu.h +1 -1
  10. data/ext/zstdruby/libzstd/common/mem.h +20 -2
  11. data/ext/zstdruby/libzstd/common/xxhash.c +1 -0
  12. data/ext/zstdruby/libzstd/common/zstd_internal.h +3 -2
  13. data/ext/zstdruby/libzstd/compress/fse_compress.c +55 -48
  14. data/ext/zstdruby/libzstd/compress/hist.h +1 -1
  15. data/ext/zstdruby/libzstd/compress/huf_compress.c +1 -1
  16. data/ext/zstdruby/libzstd/compress/zstd_compress.c +290 -147
  17. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +5 -2
  18. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +63 -51
  19. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -4
  20. data/ext/zstdruby/libzstd/compress/zstd_fast.c +44 -33
  21. data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -4
  22. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +125 -116
  23. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +13 -15
  24. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +9 -11
  25. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +0 -1
  26. data/ext/zstdruby/libzstd/compress/zstd_opt.c +42 -36
  27. data/ext/zstdruby/libzstd/compress/zstd_opt.h +8 -9
  28. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +96 -51
  29. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +16 -6
  30. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +3 -3
  31. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +169 -101
  32. data/ext/zstdruby/libzstd/dictBuilder/cover.c +111 -87
  33. data/ext/zstdruby/libzstd/dictBuilder/cover.h +83 -0
  34. data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +3 -3
  35. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +728 -0
  36. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +34 -31
  37. data/ext/zstdruby/libzstd/dictBuilder/zdict.h +60 -5
  38. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +9 -3
  39. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +6 -0
  40. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +6 -0
  41. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -5
  42. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +12 -9
  43. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +10 -10
  44. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +20 -18
  45. data/ext/zstdruby/libzstd/zstd.h +109 -50
  46. data/lib/zstd-ruby/version.rb +1 -1
  47. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4db2d13ebb9e0ebf43163566e394eb1aa2e5db44963cbb0b9d2863361114aa9
4
- data.tar.gz: f2d6666a402d2ccdf4138783b696f34c3a1d5eaed2a94887a39ddf5b6892df2f
3
+ metadata.gz: 35d073986861ccb9bdb6a87e3f7335dd5d08249913c668a6d6279aadcfca7551
4
+ data.tar.gz: 315406589d9487c367edd70a2dc9c090dd796b0764fb1d4200a32b4375c430bc
5
5
  SHA512:
6
- metadata.gz: 3e55fb48e38220cf3c6e50297f9b440b833e8061b2f76578a575d42126a5e59586ec6331522b85cb524b779a1f94cf26722d121d1019cb4f05e90968e28fa7c7
7
- data.tar.gz: dba96481652009782745374a972ffdb3aff127b21f93d5adff3e1a2d425cf48c3396b7d12f63d0964db6dfb96715c04d92bd2794759367185b81f645d366ffdd
6
+ metadata.gz: 4395106140fe83001703df637cb1632f7ef17cba187d9935c385d30b8c3a06a8688d9a169f4c9cbd1cb1d53463b895c1e414503f8030b7115ff8e612510cba9b
7
+ data.tar.gz: ab48fc82d7d1eef1179242839d93ea3cd2eb88e27b3dc4957d3457a4cf125bf0764f48b2c28ae626346bb3866c6a81114da2de6c75547f80a4e1589dc8032689
data/.travis.yml CHANGED
@@ -1,8 +1,10 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.1
5
- - 2.3.3
4
+ - 2.6.0
5
+ - 2.5.3
6
+ - 2.4.5
7
+ - 2.3.8
6
8
  - 2.2
7
9
 
8
10
  before_install: gem install bundler -v 1.14.3
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ [![Gem Version](https://badge.fury.io/rb/zstd-ruby.svg)](https://badge.fury.io/rb/zstd-ruby)
1
2
  [![Build Status](https://travis-ci.org/SpringMT/zstd-ruby.svg?branch=master)](https://travis-ci.org/SpringMT/zstd-ruby)
2
3
 
3
4
  # zstd-ruby
@@ -9,7 +10,7 @@ See https://github.com/facebook/zstd
9
10
  Fork from https://github.com/jarredholman/ruby-zstd.
10
11
 
11
12
  ## Zstd version
12
- v1.3.5 (https://github.com/facebook/zstd/tree/v1.3.5)
13
+ v1.3.7 (https://github.com/facebook/zstd/tree/v1.3.7)
13
14
 
14
15
  ## Installation
15
16
 
@@ -69,6 +69,7 @@ cxx_library(
69
69
  ]),
70
70
  headers=subdir_glob([
71
71
  ('dictBuilder', 'divsufsort.h'),
72
+ ('dictBuilder', 'cover.h'),
72
73
  ]),
73
74
  srcs=glob(['dictBuilder/*.c']),
74
75
  deps=[':common'],
@@ -19,15 +19,20 @@ LIBVER := $(shell echo $(LIBVER_SCRIPT))
19
19
  VERSION?= $(LIBVER)
20
20
 
21
21
  CPPFLAGS+= -I. -I./common -DXXH_NAMESPACE=ZSTD_
22
+ ifeq ($(OS),Windows_NT) # MinGW assumed
23
+ CPPFLAGS += -D__USE_MINGW_ANSI_STDIO # compatibility with %zu formatting
24
+ endif
22
25
  CFLAGS ?= -O3
23
- DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
26
+ DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
24
27
  -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
25
28
  -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
26
29
  -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
27
- -Wredundant-decls
30
+ -Wredundant-decls -Wmissing-prototypes
28
31
  CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
29
32
  FLAGS = $(CPPFLAGS) $(CFLAGS)
30
33
 
34
+ GREP = grep --color=never
35
+
31
36
  ZSTDCOMMON_FILES := $(sort $(wildcard common/*.c))
32
37
  ZSTDCOMP_FILES := $(sort $(wildcard compress/*.c))
33
38
  ZSTDDECOMP_FILES := $(sort $(wildcard decompress/*.c))
@@ -35,7 +40,7 @@ ZDICT_FILES := $(sort $(wildcard dictBuilder/*.c))
35
40
  ZDEPR_FILES := $(sort $(wildcard deprecated/*.c))
36
41
  ZSTD_FILES := $(ZSTDCOMMON_FILES)
37
42
 
38
- ZSTD_LEGACY_SUPPORT ?= 4
43
+ ZSTD_LEGACY_SUPPORT ?= 5
39
44
  ZSTD_LIB_COMPRESSION ?= 1
40
45
  ZSTD_LIB_DECOMPRESSION ?= 1
41
46
  ZSTD_LIB_DICTBUILDER ?= 1
@@ -52,11 +57,11 @@ ifeq ($(ZSTD_LIB_DECOMPRESSION), 0)
52
57
  endif
53
58
 
54
59
  ifneq ($(ZSTD_LIB_COMPRESSION), 0)
55
- ZSTD_FILES += $(ZSTDCOMP_FILES)
60
+ ZSTD_FILES += $(ZSTDCOMP_FILES)
56
61
  endif
57
62
 
58
63
  ifneq ($(ZSTD_LIB_DECOMPRESSION), 0)
59
- ZSTD_FILES += $(ZSTDDECOMP_FILES)
64
+ ZSTD_FILES += $(ZSTDDECOMP_FILES)
60
65
  endif
61
66
 
62
67
  ifneq ($(ZSTD_LIB_DEPRECATED), 0)
@@ -69,7 +74,7 @@ endif
69
74
 
70
75
  ifneq ($(ZSTD_LEGACY_SUPPORT), 0)
71
76
  ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT) -lt 8; echo $$?), 0)
72
- ZSTD_FILES += $(shell ls legacy/*.c | grep 'v0[$(ZSTD_LEGACY_SUPPORT)-7]')
77
+ ZSTD_FILES += $(shell ls legacy/*.c | $(GREP) 'v0[$(ZSTD_LEGACY_SUPPORT)-7]')
73
78
  endif
74
79
  CPPFLAGS += -I./legacy
75
80
  endif
@@ -91,8 +96,6 @@ else
91
96
  SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER)
92
97
  endif
93
98
 
94
- LIBZSTD = libzstd.$(SHARED_EXT_VER)
95
-
96
99
 
97
100
  .PHONY: default all clean install uninstall
98
101
 
@@ -108,19 +111,28 @@ libzstd.a: $(ZSTD_OBJ)
108
111
  libzstd.a-mt: CPPFLAGS += -DZSTD_MULTITHREAD
109
112
  libzstd.a-mt: libzstd.a
110
113
 
111
- $(LIBZSTD): LDFLAGS += -shared -fPIC -fvisibility=hidden
114
+ ifneq (,$(filter Windows%,$(OS)))
115
+
116
+ LIBZSTD = dll\libzstd.dll
112
117
  $(LIBZSTD): $(ZSTD_FILES)
113
118
  @echo compiling dynamic library $(LIBVER)
114
- ifneq (,$(filter Windows%,$(OS)))
115
- @$(CC) $(FLAGS) -DZSTD_DLL_EXPORT=1 -shared $^ -o dll\libzstd.dll
116
- dlltool -D dll\libzstd.dll -d dll\libzstd.def -l dll\libzstd.lib
119
+ @$(CC) $(FLAGS) -DZSTD_DLL_EXPORT=1 -shared $^ -o $@
120
+ dlltool -D $@ -d dll\libzstd.def -l dll\libzstd.lib
121
+
117
122
  else
123
+
124
+ LIBZSTD = libzstd.$(SHARED_EXT_VER)
125
+ $(LIBZSTD): LDFLAGS += -shared -fPIC -fvisibility=hidden
126
+ $(LIBZSTD): $(ZSTD_FILES)
127
+ @echo compiling dynamic library $(LIBVER)
118
128
  @$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
119
129
  @echo creating versioned links
120
130
  @ln -sf $@ libzstd.$(SHARED_EXT_MAJOR)
121
131
  @ln -sf $@ libzstd.$(SHARED_EXT)
132
+
122
133
  endif
123
134
 
135
+
124
136
  libzstd : $(LIBZSTD)
125
137
 
126
138
  libzstd-mt : CPPFLAGS += -DZSTD_MULTITHREAD
@@ -154,7 +166,7 @@ clean:
154
166
  #-----------------------------------------------------------------------------
155
167
  # make install is validated only for Linux, macOS, BSD, Hurd and Solaris targets
156
168
  #-----------------------------------------------------------------------------
157
- ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS))
169
+ ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku))
158
170
 
159
171
  DESTDIR ?=
160
172
  # directory variables : GNU conventions prefer lowercase
@@ -13,7 +13,7 @@ including commands variables, staged install, directory variables and standard t
13
13
  - `make install` : install libraries in default system directories
14
14
 
15
15
  `libzstd` default scope includes compression, decompression, dictionary building,
16
- and decoding support for legacy formats >= v0.4.0.
16
+ and decoding support for legacy formats >= v0.5.0.
17
17
 
18
18
 
19
19
  #### API
@@ -48,23 +48,24 @@ It's possible to compile only a limited set of features.
48
48
  This module depends on both `lib/common` and `lib/compress` .
49
49
  - `lib/legacy` : source code to decompress legacy zstd formats, starting from `v0.1.0`.
50
50
  This module depends on `lib/common` and `lib/decompress`.
51
- To enable this feature, it's required to define `ZSTD_LEGACY_SUPPORT` during compilation.
52
- Typically, with `gcc`, add argument `-DZSTD_LEGACY_SUPPORT=1`.
53
- Using higher number limits versions supported.
51
+ To enable this feature, define `ZSTD_LEGACY_SUPPORT` during compilation.
52
+ Specifying a number limits versions supported to that version onward.
54
53
  For example, `ZSTD_LEGACY_SUPPORT=2` means : "support legacy formats >= v0.2.0".
55
54
  `ZSTD_LEGACY_SUPPORT=3` means : "support legacy formats >= v0.3.0", and so on.
56
- Starting v0.8.0, all versions of `zstd` produce frames compliant with specification.
57
- As a consequence, `ZSTD_LEGACY_SUPPORT=8` (or more) doesn't trigger legacy support.
58
- Also, `ZSTD_LEGACY_SUPPORT=0` means "do __not__ support legacy formats".
55
+ Currently, the default library setting is `ZST_LEGACY_SUPPORT=5`.
56
+ It can be changed at build by any other value.
57
+ Note that any number >= 8 translates into "do __not__ support legacy formats",
58
+ since all versions of `zstd` >= v0.8 are compatible with v1+ specification.
59
+ `ZSTD_LEGACY_SUPPORT=0` also means "do __not__ support legacy formats".
59
60
  Once enabled, this capability is transparently triggered within decompression functions.
60
61
  It's also possible to invoke directly legacy API, as exposed in `lib/legacy/zstd_legacy.h`.
61
62
  Each version also provides an additional dedicated set of advanced API.
62
63
  For example, advanced API for version `v0.4` is exposed in `lib/legacy/zstd_v04.h` .
63
64
  Note : `lib/legacy` only supports _decoding_ legacy formats.
64
- - Similarly, you can define `ZSTD_LIB_COMPRESSION, ZSTD_LIB_DECOMPRESSION`, `ZSTD_LIB_DICTBUILDER`,
65
- and `ZSTD_LIB_DEPRECATED` as 0 to forgo compilation of the corresponding features. This will
65
+ - Similarly, you can define `ZSTD_LIB_COMPRESSION, ZSTD_LIB_DECOMPRESSION`, `ZSTD_LIB_DICTBUILDER`,
66
+ and `ZSTD_LIB_DEPRECATED` as 0 to forgo compilation of the corresponding features. This will
66
67
  also disable compilation of all dependencies (eg. `ZSTD_LIB_COMPRESSION=0` will also disable
67
- dictBuilder).
68
+ dictBuilder).
68
69
 
69
70
 
70
71
  #### Multithreading support
@@ -339,17 +339,10 @@ MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
339
339
 
340
340
  MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
341
341
  {
342
- #if defined(__BMI__) && defined(__GNUC__) && __GNUC__*1000+__GNUC_MINOR__ >= 4008 /* experimental */
343
- # if defined(__x86_64__)
344
- if (sizeof(bitContainer)==8)
345
- return _bextr_u64(bitContainer, start, nbBits);
346
- else
347
- # endif
348
- return _bextr_u32(bitContainer, start, nbBits);
349
- #else
342
+ U32 const regMask = sizeof(bitContainer)*8 - 1;
343
+ /* if start > regMask, bitstream is corrupted, and result is undefined */
350
344
  assert(nbBits < BIT_MASK_SIZE);
351
- return (bitContainer >> start) & BIT_mask[nbBits];
352
- #endif
345
+ return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
353
346
  }
354
347
 
355
348
  MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
@@ -366,9 +359,13 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
366
359
  * @return : value extracted */
367
360
  MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
368
361
  {
369
- #if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */
362
+ /* arbitrate between double-shift and shift+mask */
363
+ #if 1
364
+ /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8,
365
+ * bitstream is likely corrupted, and result is undefined */
370
366
  return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
371
367
  #else
368
+ /* this code path is slower on my os-x laptop */
372
369
  U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
373
370
  return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask);
374
371
  #endif
@@ -88,15 +88,37 @@
88
88
  #endif
89
89
  #endif
90
90
 
91
- /* prefetch */
92
- #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
93
- # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
94
- # define PREFETCH(ptr) _mm_prefetch((const char*)ptr, _MM_HINT_T0)
95
- #elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
96
- # define PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0)
91
+ /* prefetch
92
+ * can be disabled, by declaring NO_PREFETCH macro
93
+ * All prefetch invocations use a single default locality 2,
94
+ * generating instruction prefetcht1,
95
+ * which, according to Intel, means "load data into L2 cache".
96
+ * This is a good enough "middle ground" for the time being,
97
+ * though in theory, it would be better to specialize locality depending on data being prefetched.
98
+ * Tests could not determine any sensible difference based on locality value. */
99
+ #if defined(NO_PREFETCH)
100
+ # define PREFETCH(ptr) (void)(ptr) /* disabled */
97
101
  #else
98
- # define PREFETCH(ptr) /* disabled */
99
- #endif
102
+ # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
103
+ # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
104
+ # define PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
105
+ # elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
106
+ # define PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
107
+ # else
108
+ # define PREFETCH(ptr) (void)(ptr) /* disabled */
109
+ # endif
110
+ #endif /* NO_PREFETCH */
111
+
112
+ #define CACHELINE_SIZE 64
113
+
114
+ #define PREFETCH_AREA(p, s) { \
115
+ const char* const _ptr = (const char*)(p); \
116
+ size_t const _size = (size_t)(s); \
117
+ size_t _pos; \
118
+ for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
119
+ PREFETCH(_ptr + _pos); \
120
+ } \
121
+ }
100
122
 
101
123
  /* disable warnings */
102
124
  #ifdef _MSC_VER /* Visual Studio */
@@ -36,7 +36,7 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
36
36
  U32 f1d = 0;
37
37
  U32 f7b = 0;
38
38
  U32 f7c = 0;
39
- #ifdef _MSC_VER
39
+ #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
40
40
  int reg[4];
41
41
  __cpuid((int*)reg, 0);
42
42
  {
@@ -39,6 +39,10 @@ extern "C" {
39
39
  # define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
40
40
  #endif
41
41
 
42
+ #ifndef __has_builtin
43
+ # define __has_builtin(x) 0 /* compat. with non-clang compilers */
44
+ #endif
45
+
42
46
  /* code only tested on 32 and 64 bits systems */
43
47
  #define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; }
44
48
  MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
@@ -57,11 +61,23 @@ MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (size
57
61
  typedef uint64_t U64;
58
62
  typedef int64_t S64;
59
63
  #else
64
+ # include <limits.h>
65
+ #if CHAR_BIT != 8
66
+ # error "this implementation requires char to be exactly 8-bit type"
67
+ #endif
60
68
  typedef unsigned char BYTE;
69
+ #if USHRT_MAX != 65535
70
+ # error "this implementation requires short to be exactly 16-bit type"
71
+ #endif
61
72
  typedef unsigned short U16;
62
73
  typedef signed short S16;
74
+ #if UINT_MAX != 4294967295
75
+ # error "this implementation requires int to be exactly 32-bit type"
76
+ #endif
63
77
  typedef unsigned int U32;
64
78
  typedef signed int S32;
79
+ /* note : there are no limits defined for long long type in C90.
80
+ * limits exist in C99, however, in such case, <stdint.h> is preferred */
65
81
  typedef unsigned long long U64;
66
82
  typedef signed long long S64;
67
83
  #endif
@@ -186,7 +202,8 @@ MEM_STATIC U32 MEM_swap32(U32 in)
186
202
  {
187
203
  #if defined(_MSC_VER) /* Visual Studio */
188
204
  return _byteswap_ulong(in);
189
- #elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
205
+ #elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
206
+ || (defined(__clang__) && __has_builtin(__builtin_bswap32))
190
207
  return __builtin_bswap32(in);
191
208
  #else
192
209
  return ((in << 24) & 0xff000000 ) |
@@ -200,7 +217,8 @@ MEM_STATIC U64 MEM_swap64(U64 in)
200
217
  {
201
218
  #if defined(_MSC_VER) /* Visual Studio */
202
219
  return _byteswap_uint64(in);
203
- #elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
220
+ #elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
221
+ || (defined(__clang__) && __has_builtin(__builtin_bswap64))
204
222
  return __builtin_bswap64(in);
205
223
  #else
206
224
  return ((in << 56) & 0xff00000000000000ULL) |
@@ -98,6 +98,7 @@
98
98
  /* Modify the local functions below should you wish to use some other memory routines */
99
99
  /* for malloc(), free() */
100
100
  #include <stdlib.h>
101
+ #include <stddef.h> /* size_t */
101
102
  static void* XXH_malloc(size_t s) { return malloc(s); }
102
103
  static void XXH_free (void* p) { free(p); }
103
104
  /* for memcpy() */
@@ -79,8 +79,7 @@ static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
79
79
  static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
80
80
  static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
81
81
 
82
- #define ZSTD_FRAMEIDSIZE 4
83
- static const size_t ZSTD_frameIdSize = ZSTD_FRAMEIDSIZE; /* magic number size */
82
+ #define ZSTD_FRAMEIDSIZE 4 /* magic number size */
84
83
 
85
84
  #define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
86
85
  static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
@@ -193,6 +192,8 @@ typedef struct {
193
192
  BYTE* llCode;
194
193
  BYTE* mlCode;
195
194
  BYTE* ofCode;
195
+ size_t maxNbSeq;
196
+ size_t maxNbLit;
196
197
  U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
197
198
  U32 longLengthPos;
198
199
  } seqStore_t;
@@ -83,7 +83,9 @@
83
83
  * wkspSize should be sized to handle worst case situation, which is `1<<max_tableLog * sizeof(FSE_FUNCTION_TYPE)`
84
84
  * workSpace must also be properly aligned with FSE_FUNCTION_TYPE requirements
85
85
  */
86
- size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
86
+ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
87
+ const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
88
+ void* workSpace, size_t wkspSize)
87
89
  {
88
90
  U32 const tableSize = 1 << tableLog;
89
91
  U32 const tableMask = tableSize - 1;
@@ -101,10 +103,14 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsi
101
103
  if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);
102
104
  tableU16[-2] = (U16) tableLog;
103
105
  tableU16[-1] = (U16) maxSymbolValue;
104
- assert(tableLog < 16); /* required for the threshold strategy to work */
106
+ assert(tableLog < 16); /* required for threshold strategy to work */
105
107
 
106
108
  /* For explanations on how to distribute symbol values over the table :
107
- * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
109
+ * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
110
+
111
+ #ifdef __clang_analyzer__
112
+ memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */
113
+ #endif
108
114
 
109
115
  /* symbol start positions */
110
116
  { U32 u;
@@ -124,13 +130,15 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsi
124
130
  U32 symbol;
125
131
  for (symbol=0; symbol<=maxSymbolValue; symbol++) {
126
132
  int nbOccurences;
127
- for (nbOccurences=0; nbOccurences<normalizedCounter[symbol]; nbOccurences++) {
133
+ int const freq = normalizedCounter[symbol];
134
+ for (nbOccurences=0; nbOccurences<freq; nbOccurences++) {
128
135
  tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
129
136
  position = (position + step) & tableMask;
130
- while (position > highThreshold) position = (position + step) & tableMask; /* Low proba area */
137
+ while (position > highThreshold)
138
+ position = (position + step) & tableMask; /* Low proba area */
131
139
  } }
132
140
 
133
- if (position!=0) return ERROR(GENERIC); /* Must have gone through all positions */
141
+ assert(position==0); /* Must have initialized all positions */
134
142
  }
135
143
 
136
144
  /* Build table */
@@ -201,9 +209,10 @@ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
201
209
  return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
202
210
  }
203
211
 
204
- static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
205
- const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
206
- unsigned writeIsSafe)
212
+ static size_t
213
+ FSE_writeNCount_generic (void* header, size_t headerBufferSize,
214
+ const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
215
+ unsigned writeIsSafe)
207
216
  {
208
217
  BYTE* const ostart = (BYTE*) header;
209
218
  BYTE* out = ostart;
@@ -212,13 +221,12 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
212
221
  const int tableSize = 1 << tableLog;
213
222
  int remaining;
214
223
  int threshold;
215
- U32 bitStream;
216
- int bitCount;
217
- unsigned charnum = 0;
218
- int previous0 = 0;
224
+ U32 bitStream = 0;
225
+ int bitCount = 0;
226
+ unsigned symbol = 0;
227
+ unsigned const alphabetSize = maxSymbolValue + 1;
228
+ int previousIs0 = 0;
219
229
 
220
- bitStream = 0;
221
- bitCount = 0;
222
230
  /* Table Size */
223
231
  bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
224
232
  bitCount += 4;
@@ -228,48 +236,53 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
228
236
  threshold = tableSize;
229
237
  nbBits = tableLog+1;
230
238
 
231
- while (remaining>1) { /* stops at 1 */
232
- if (previous0) {
233
- unsigned start = charnum;
234
- while (!normalizedCounter[charnum]) charnum++;
235
- while (charnum >= start+24) {
239
+ while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */
240
+ if (previousIs0) {
241
+ unsigned start = symbol;
242
+ while ((symbol < alphabetSize) && !normalizedCounter[symbol]) symbol++;
243
+ if (symbol == alphabetSize) break; /* incorrect distribution */
244
+ while (symbol >= start+24) {
236
245
  start+=24;
237
246
  bitStream += 0xFFFFU << bitCount;
238
- if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
247
+ if ((!writeIsSafe) && (out > oend-2))
248
+ return ERROR(dstSize_tooSmall); /* Buffer overflow */
239
249
  out[0] = (BYTE) bitStream;
240
250
  out[1] = (BYTE)(bitStream>>8);
241
251
  out+=2;
242
252
  bitStream>>=16;
243
253
  }
244
- while (charnum >= start+3) {
254
+ while (symbol >= start+3) {
245
255
  start+=3;
246
256
  bitStream += 3 << bitCount;
247
257
  bitCount += 2;
248
258
  }
249
- bitStream += (charnum-start) << bitCount;
259
+ bitStream += (symbol-start) << bitCount;
250
260
  bitCount += 2;
251
261
  if (bitCount>16) {
252
- if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
262
+ if ((!writeIsSafe) && (out > oend - 2))
263
+ return ERROR(dstSize_tooSmall); /* Buffer overflow */
253
264
  out[0] = (BYTE)bitStream;
254
265
  out[1] = (BYTE)(bitStream>>8);
255
266
  out += 2;
256
267
  bitStream >>= 16;
257
268
  bitCount -= 16;
258
269
  } }
259
- { int count = normalizedCounter[charnum++];
260
- int const max = (2*threshold-1)-remaining;
270
+ { int count = normalizedCounter[symbol++];
271
+ int const max = (2*threshold-1) - remaining;
261
272
  remaining -= count < 0 ? -count : count;
262
273
  count++; /* +1 for extra accuracy */
263
- if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
274
+ if (count>=threshold)
275
+ count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
264
276
  bitStream += count << bitCount;
265
277
  bitCount += nbBits;
266
278
  bitCount -= (count<max);
267
- previous0 = (count==1);
279
+ previousIs0 = (count==1);
268
280
  if (remaining<1) return ERROR(GENERIC);
269
281
  while (remaining<threshold) { nbBits--; threshold>>=1; }
270
282
  }
271
283
  if (bitCount>16) {
272
- if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
284
+ if ((!writeIsSafe) && (out > oend - 2))
285
+ return ERROR(dstSize_tooSmall); /* Buffer overflow */
273
286
  out[0] = (BYTE)bitStream;
274
287
  out[1] = (BYTE)(bitStream>>8);
275
288
  out += 2;
@@ -277,19 +290,23 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
277
290
  bitCount -= 16;
278
291
  } }
279
292
 
293
+ if (remaining != 1)
294
+ return ERROR(GENERIC); /* incorrect normalized distribution */
295
+ assert(symbol <= alphabetSize);
296
+
280
297
  /* flush remaining bitStream */
281
- if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
298
+ if ((!writeIsSafe) && (out > oend - 2))
299
+ return ERROR(dstSize_tooSmall); /* Buffer overflow */
282
300
  out[0] = (BYTE)bitStream;
283
301
  out[1] = (BYTE)(bitStream>>8);
284
302
  out+= (bitCount+7) /8;
285
303
 
286
- if (charnum > maxSymbolValue + 1) return ERROR(GENERIC);
287
-
288
304
  return (out-ostart);
289
305
  }
290
306
 
291
307
 
292
- size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
308
+ size_t FSE_writeNCount (void* buffer, size_t bufferSize,
309
+ const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
293
310
  {
294
311
  if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */
295
312
  if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */
@@ -297,26 +314,13 @@ size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalized
297
314
  if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
298
315
  return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
299
316
 
300
- return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
317
+ return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1 /* write in buffer is safe */);
301
318
  }
302
319
 
303
320
 
304
321
  /*-**************************************************************
305
322
  * FSE Compression Code
306
323
  ****************************************************************/
307
- /*! FSE_sizeof_CTable() :
308
- FSE_CTable is a variable size structure which contains :
309
- `U16 tableLog;`
310
- `U16 maxSymbolValue;`
311
- `U16 nextStateNumber[1 << tableLog];` // This size is variable
312
- `FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];` // This size is variable
313
- Allocation is manual (C standard does not support variable-size structures).
314
- */
315
- size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
316
- {
317
- if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
318
- return FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
319
- }
320
324
 
321
325
  FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
322
326
  {
@@ -331,7 +335,7 @@ void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
331
335
  /* provides the minimum logSize to safely represent a distribution */
332
336
  static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
333
337
  {
334
- U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
338
+ U32 minBitsSrc = BIT_highbit32((U32)(srcSize)) + 1;
335
339
  U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
336
340
  U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
337
341
  assert(srcSize > 1); /* Not supported, RLE should be used instead */
@@ -394,6 +398,9 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
394
398
  }
395
399
  ToDistribute = (1 << tableLog) - distributed;
396
400
 
401
+ if (ToDistribute == 0)
402
+ return 0;
403
+
397
404
  if ((total / ToDistribute) > lowOne) {
398
405
  /* risk of rounding to zero */
399
406
  lowOne = (U32)((total * 3) / (ToDistribute * 2));