zstd-ruby 1.4.5.0 → 1.5.5.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.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +78 -5
  4. data/Rakefile +8 -2
  5. data/ext/zstdruby/common.h +15 -0
  6. data/ext/zstdruby/extconf.rb +3 -2
  7. data/ext/zstdruby/libzstd/common/allocations.h +55 -0
  8. data/ext/zstdruby/libzstd/common/bits.h +200 -0
  9. data/ext/zstdruby/libzstd/common/bitstream.h +45 -62
  10. data/ext/zstdruby/libzstd/common/compiler.h +205 -22
  11. data/ext/zstdruby/libzstd/common/cpu.h +1 -3
  12. data/ext/zstdruby/libzstd/common/debug.c +1 -1
  13. data/ext/zstdruby/libzstd/common/debug.h +12 -19
  14. data/ext/zstdruby/libzstd/common/entropy_common.c +172 -48
  15. data/ext/zstdruby/libzstd/common/error_private.c +10 -2
  16. data/ext/zstdruby/libzstd/common/error_private.h +82 -3
  17. data/ext/zstdruby/libzstd/common/fse.h +37 -86
  18. data/ext/zstdruby/libzstd/common/fse_decompress.c +117 -92
  19. data/ext/zstdruby/libzstd/common/huf.h +99 -166
  20. data/ext/zstdruby/libzstd/common/mem.h +124 -142
  21. data/ext/zstdruby/libzstd/common/pool.c +54 -27
  22. data/ext/zstdruby/libzstd/common/pool.h +10 -4
  23. data/ext/zstdruby/libzstd/common/portability_macros.h +156 -0
  24. data/ext/zstdruby/libzstd/common/threading.c +74 -19
  25. data/ext/zstdruby/libzstd/common/threading.h +5 -10
  26. data/ext/zstdruby/libzstd/common/xxhash.c +7 -847
  27. data/ext/zstdruby/libzstd/common/xxhash.h +5568 -167
  28. data/ext/zstdruby/libzstd/common/zstd_common.c +2 -37
  29. data/ext/zstdruby/libzstd/common/zstd_deps.h +111 -0
  30. data/ext/zstdruby/libzstd/common/zstd_internal.h +132 -187
  31. data/ext/zstdruby/libzstd/common/zstd_trace.h +163 -0
  32. data/ext/zstdruby/libzstd/compress/clevels.h +134 -0
  33. data/ext/zstdruby/libzstd/compress/fse_compress.c +83 -157
  34. data/ext/zstdruby/libzstd/compress/hist.c +27 -29
  35. data/ext/zstdruby/libzstd/compress/hist.h +2 -2
  36. data/ext/zstdruby/libzstd/compress/huf_compress.c +916 -279
  37. data/ext/zstdruby/libzstd/compress/zstd_compress.c +3773 -1019
  38. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +610 -203
  39. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +119 -42
  40. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +16 -6
  41. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +42 -19
  42. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
  43. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +49 -317
  44. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
  45. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +320 -103
  46. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +388 -151
  47. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -2
  48. data/ext/zstdruby/libzstd/compress/zstd_fast.c +729 -265
  49. data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -2
  50. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +1270 -251
  51. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +61 -1
  52. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +324 -219
  53. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +9 -2
  54. data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +106 -0
  55. data/ext/zstdruby/libzstd/compress/zstd_opt.c +481 -209
  56. data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
  57. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +181 -457
  58. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +34 -113
  59. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +1199 -565
  60. data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +576 -0
  61. data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +12 -12
  62. data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +2 -2
  63. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +627 -157
  64. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +1086 -326
  65. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +19 -5
  66. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +62 -13
  67. data/ext/zstdruby/libzstd/dictBuilder/cover.c +73 -52
  68. data/ext/zstdruby/libzstd/dictBuilder/cover.h +7 -6
  69. data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +1 -1
  70. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +44 -35
  71. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +103 -111
  72. data/ext/zstdruby/libzstd/{dictBuilder/zdict.h → zdict.h} +203 -34
  73. data/ext/zstdruby/libzstd/zstd.h +1217 -287
  74. data/ext/zstdruby/libzstd/{common/zstd_errors.h → zstd_errors.h} +28 -8
  75. data/ext/zstdruby/main.c +20 -0
  76. data/ext/zstdruby/skippable_frame.c +63 -0
  77. data/ext/zstdruby/streaming_compress.c +177 -0
  78. data/ext/zstdruby/streaming_compress.h +5 -0
  79. data/ext/zstdruby/streaming_decompress.c +123 -0
  80. data/ext/zstdruby/zstdruby.c +114 -32
  81. data/lib/zstd-ruby/version.rb +1 -1
  82. data/lib/zstd-ruby.rb +0 -1
  83. data/zstd-ruby.gemspec +1 -1
  84. metadata +19 -36
  85. data/.travis.yml +0 -14
  86. data/ext/zstdruby/libzstd/.gitignore +0 -3
  87. data/ext/zstdruby/libzstd/BUCK +0 -234
  88. data/ext/zstdruby/libzstd/Makefile +0 -354
  89. data/ext/zstdruby/libzstd/README.md +0 -179
  90. data/ext/zstdruby/libzstd/deprecated/zbuff.h +0 -214
  91. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +0 -26
  92. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +0 -147
  93. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +0 -75
  94. data/ext/zstdruby/libzstd/dll/example/Makefile +0 -48
  95. data/ext/zstdruby/libzstd/dll/example/README.md +0 -69
  96. data/ext/zstdruby/libzstd/dll/example/build_package.bat +0 -20
  97. data/ext/zstdruby/libzstd/dll/example/fullbench-dll.sln +0 -25
  98. data/ext/zstdruby/libzstd/dll/example/fullbench-dll.vcxproj +0 -181
  99. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +0 -415
  100. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +0 -2158
  101. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +0 -94
  102. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +0 -3518
  103. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +0 -93
  104. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +0 -3160
  105. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +0 -93
  106. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +0 -3647
  107. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +0 -142
  108. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +0 -4050
  109. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +0 -162
  110. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +0 -4154
  111. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +0 -172
  112. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +0 -4541
  113. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +0 -187
  114. data/ext/zstdruby/libzstd/libzstd.pc.in +0 -15
  115. data/ext/zstdruby/zstdruby.h +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3fb9daf94529e91f7b648c1d29d5d562463553adb5d4ac420121bac1804fbeab
4
- data.tar.gz: bdcebd2d2709f7b1c1736343846bf78c8b528237a78e45d3e7fd7c1473275ed4
3
+ metadata.gz: 76dbffc6a0a13fccd92ea93abd90e33c4a26ab2ac2972877b7928a515e37033e
4
+ data.tar.gz: 21e3eba574ac94d9f34ac0d33732435ed3fd2373e9db921702a74d2a2c9d606a
5
5
  SHA512:
6
- metadata.gz: 3e615781ba60a8525498fc5329917762411cfc4edf465ce9be06dbee5d9f08ff4bcf119142e2d61e5285f5efb94accc28d50f356d1f91cbf7d34d4531fb341f4
7
- data.tar.gz: 87fa77e13997a63109ba65e6cf38ad429192ca62991bb600a27660762fc1381c4dfd3ea9e5561b3a17774b3e3967483a095481259bcd653aa72469c823aa929f
6
+ metadata.gz: 4f8c40ad6eaa9b014467fc57651f857713767f7930b2e7e2060c50ff58d05262416d0e9cb1427f440298af577eeef5247daec1866a55003ca6d9b2e2ea6212de
7
+ data.tar.gz: 5836f8061f7588081df400bf0705fcc74003029ec9ef9225e43f5ba5a0b19ec747af71cf0e34f150212a5efd90b9e1ea5ebe49a7231297e3f2ab8080bbf8247d
data/.gitignore CHANGED
@@ -17,3 +17,5 @@ vendor/
17
17
 
18
18
  # rspec failure tracking
19
19
  .rspec_status
20
+
21
+ .ruby-version
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/zstd-ruby.svg)](https://badge.fury.io/rb/zstd-ruby)
2
- [![Build Status](https://travis-ci.org/SpringMT/zstd-ruby.svg?branch=master)](https://travis-ci.org/SpringMT/zstd-ruby)
2
+ ![Build Status](https://github.com/SpringMT/zstd-ruby/actions/workflows/ruby.yml/badge.svg?branch=main)
3
3
 
4
4
  # zstd-ruby
5
5
 
@@ -10,7 +10,7 @@ See https://github.com/facebook/zstd
10
10
  Fork from https://github.com/jarredholman/ruby-zstd.
11
11
 
12
12
  ## Zstd version
13
- v1.4.5 (https://github.com/facebook/zstd/tree/v1.4.5)
13
+ v1.5.5 (https://github.com/facebook/zstd/tree/v1.5.5)
14
14
 
15
15
  ## Installation
16
16
 
@@ -34,20 +34,93 @@ Or install it yourself as:
34
34
  require 'zstd-ruby'
35
35
  ```
36
36
 
37
- ### compression
37
+ ### Simple Compression
38
38
 
39
39
  ```ruby
40
40
  compressed_data = Zstd.compress(data)
41
41
  compressed_data = Zstd.compress(data, complession_level) # default compression_level is 0
42
42
  ```
43
43
 
44
+ ### Compression using Dictionary
45
+ ```ruby
46
+ # dictionary is supposed to have been created using `zstd --train`
47
+ compressed_using_dict = Zstd.compress_using_dict("", IO.read('dictionary_file'))
48
+ ```
49
+
50
+ ### Streaming Compression
51
+ ```ruby
52
+ stream = Zstd::StreamingCompress.new
53
+ stream << "abc" << "def"
54
+ res = stream.flush
55
+ stream << "ghi"
56
+ res << stream.finish
57
+ ```
44
58
 
45
- ### decompression
59
+ or
60
+
61
+ ```ruby
62
+ stream = Zstd::StreamingCompress.new
63
+ res = stream.compress("abc")
64
+ res << stream.flush
65
+ res << stream.compress("def")
66
+ res << stream.finish
67
+ ```
68
+
69
+ ### Simple Decompression
46
70
 
47
71
  ```ruby
48
72
  data = Zstd.decompress(compressed_data)
49
73
  ```
50
74
 
75
+ ### Decomporession using Dictionary
76
+ ```ruby
77
+ # dictionary is supposed to have been created using `zstd --train`
78
+ Zstd.decompress_using_dict(compressed_using_dict, IO.read('dictionary_file'))
79
+ ```
80
+
81
+ ### Streaming Decompression
82
+ ```ruby
83
+ cstr = "" # Compressed data
84
+ stream = Zstd::StreamingDecompress.new
85
+ result = ''
86
+ result << stream.decompress(cstr[0, 10])
87
+ result << stream.decompress(cstr[10..-1])
88
+ ```
89
+
90
+ ### Skippable flame
91
+
92
+ ```ruby
93
+ compressed_data_with_skippable_frame = Zstd.write_skippable_frame(compressed_data, "sample data")
94
+
95
+ Zstd.read_skippable_frame(compressed_data_with_skippable_frame)
96
+ # => "sample data"
97
+ ```
98
+
99
+ ## JRuby
100
+ This gem does not support JRuby.
101
+
102
+ Please consider using https://github.com/luben/zstd-jni.
103
+
104
+ Sample code is below.
105
+
106
+ ```
107
+ require 'java'
108
+ require_relative './zstd-jni-1.5.2-3.jar'
109
+
110
+ str = "testtest"
111
+ compressed = com.github.luben.zstd.Zstd.compress(str.to_java_bytes)
112
+ puts com.github.luben.zstd.Zstd.decompress(compressed, str.length)
113
+ ```
114
+
115
+ ```
116
+ % ls
117
+ test.rb zstd-jni-1.5.2-3.jar
118
+ % ruby -v
119
+ jruby 9.3.2.0 (2.6.8) 2021-12-01 0b8223f905 OpenJDK 64-Bit Server VM 11.0.12+0 on 11.0.12+0 +jit [darwin-x86_64]
120
+ % ruby test.rb
121
+ testtest
122
+ ```
123
+
51
124
  ## Development
52
125
 
53
126
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -56,7 +129,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
56
129
 
57
130
  ## Contributing
58
131
 
59
- Bug reports and pull requests are welcome on GitHub at https://github.com/SpringMT/zstd_ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
132
+ Bug reports and pull requests are welcome on GitHub at https://github.com/SpringMT/zstd-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
60
133
 
61
134
 
62
135
  ## License
data/Rakefile CHANGED
@@ -17,6 +17,12 @@ task :default => [:clobber, :compile, :spec]
17
17
 
18
18
  desc 'Sync zstd libs dirs to ext/zstdruby/libzstd'
19
19
  task :zstd_update do
20
- FileUtils.rm_r('ext/zstdruby/libzstd')
21
- FileUtils.cp_r('zstd/lib', 'ext/zstdruby/libzstd')
20
+ FileUtils.rm_r("ext/zstdruby/libzstd")
21
+ FileUtils.mkdir_p("ext/zstdruby/libzstd")
22
+ ["common", "compress", "decompress", "dictBuilder"].each do |dir|
23
+ FileUtils.cp_r("zstd/lib/#{dir}", "ext/zstdruby/libzstd/#{dir}")
24
+ end
25
+ FileUtils.cp_r('zstd/lib/zdict.h', 'ext/zstdruby/libzstd')
26
+ FileUtils.cp_r('zstd/lib/zstd.h', 'ext/zstdruby/libzstd')
27
+ FileUtils.cp_r('zstd/lib/zstd_errors.h', 'ext/zstdruby/libzstd')
22
28
  end
@@ -0,0 +1,15 @@
1
+ #ifndef ZSTD_RUBY_H
2
+ #define ZSTD_RUBY_H 1
3
+
4
+ #include "ruby.h"
5
+ #include "./libzstd/zstd.h"
6
+
7
+ static int convert_compression_level(VALUE compression_level_value)
8
+ {
9
+ if (NIL_P(compression_level_value)) {
10
+ return ZSTD_CLEVEL_DEFAULT;
11
+ }
12
+ return NUM2INT(compression_level_value);
13
+ }
14
+
15
+ #endif /* ZSTD_RUBY_H */
@@ -1,9 +1,10 @@
1
1
  require "mkmf"
2
2
 
3
- $CFLAGS = '-I. -O3 -std=c99'
3
+ $CFLAGS = '-I. -O3 -std=c99 -DZSTD_STATIC_LINKING_ONLY'
4
+ $CPPFLAGS += " -fdeclspec" if CONFIG['CXX'] =~ /clang/
4
5
 
5
6
  Dir.chdir File.expand_path('..', __FILE__) do
6
- $srcs = Dir['**/*.c']
7
+ $srcs = Dir['**/*.c', '**/*.S']
7
8
 
8
9
  Dir.glob('libzstd/*') do |path|
9
10
  if Dir.exist?(path)
@@ -0,0 +1,55 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ /* This file provides custom allocation primitives
12
+ */
13
+
14
+ #define ZSTD_DEPS_NEED_MALLOC
15
+ #include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */
16
+
17
+ #include "mem.h" /* MEM_STATIC */
18
+ #define ZSTD_STATIC_LINKING_ONLY
19
+ #include "../zstd.h" /* ZSTD_customMem */
20
+
21
+ #ifndef ZSTD_ALLOCATIONS_H
22
+ #define ZSTD_ALLOCATIONS_H
23
+
24
+ /* custom memory allocation functions */
25
+
26
+ MEM_STATIC void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem)
27
+ {
28
+ if (customMem.customAlloc)
29
+ return customMem.customAlloc(customMem.opaque, size);
30
+ return ZSTD_malloc(size);
31
+ }
32
+
33
+ MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem)
34
+ {
35
+ if (customMem.customAlloc) {
36
+ /* calloc implemented as malloc+memset;
37
+ * not as efficient as calloc, but next best guess for custom malloc */
38
+ void* const ptr = customMem.customAlloc(customMem.opaque, size);
39
+ ZSTD_memset(ptr, 0, size);
40
+ return ptr;
41
+ }
42
+ return ZSTD_calloc(1, size);
43
+ }
44
+
45
+ MEM_STATIC void ZSTD_customFree(void* ptr, ZSTD_customMem customMem)
46
+ {
47
+ if (ptr!=NULL) {
48
+ if (customMem.customFree)
49
+ customMem.customFree(customMem.opaque, ptr);
50
+ else
51
+ ZSTD_free(ptr);
52
+ }
53
+ }
54
+
55
+ #endif /* ZSTD_ALLOCATIONS_H */
@@ -0,0 +1,200 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #ifndef ZSTD_BITS_H
12
+ #define ZSTD_BITS_H
13
+
14
+ #include "mem.h"
15
+
16
+ MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val)
17
+ {
18
+ assert(val != 0);
19
+ {
20
+ static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3,
21
+ 30, 22, 20, 15, 25, 17, 4, 8,
22
+ 31, 27, 13, 23, 21, 19, 16, 7,
23
+ 26, 12, 18, 6, 11, 5, 10, 9};
24
+ return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27];
25
+ }
26
+ }
27
+
28
+ MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val)
29
+ {
30
+ assert(val != 0);
31
+ # if defined(_MSC_VER)
32
+ # if STATIC_BMI2 == 1
33
+ return (unsigned)_tzcnt_u32(val);
34
+ # else
35
+ if (val != 0) {
36
+ unsigned long r;
37
+ _BitScanForward(&r, val);
38
+ return (unsigned)r;
39
+ } else {
40
+ /* Should not reach this code path */
41
+ __assume(0);
42
+ }
43
+ # endif
44
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
45
+ return (unsigned)__builtin_ctz(val);
46
+ # else
47
+ return ZSTD_countTrailingZeros32_fallback(val);
48
+ # endif
49
+ }
50
+
51
+ MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) {
52
+ assert(val != 0);
53
+ {
54
+ static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29,
55
+ 11, 14, 16, 18, 22, 25, 3, 30,
56
+ 8, 12, 20, 28, 15, 17, 24, 7,
57
+ 19, 27, 23, 6, 26, 5, 4, 31};
58
+ val |= val >> 1;
59
+ val |= val >> 2;
60
+ val |= val >> 4;
61
+ val |= val >> 8;
62
+ val |= val >> 16;
63
+ return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27];
64
+ }
65
+ }
66
+
67
+ MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val)
68
+ {
69
+ assert(val != 0);
70
+ # if defined(_MSC_VER)
71
+ # if STATIC_BMI2 == 1
72
+ return (unsigned)_lzcnt_u32(val);
73
+ # else
74
+ if (val != 0) {
75
+ unsigned long r;
76
+ _BitScanReverse(&r, val);
77
+ return (unsigned)(31 - r);
78
+ } else {
79
+ /* Should not reach this code path */
80
+ __assume(0);
81
+ }
82
+ # endif
83
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
84
+ return (unsigned)__builtin_clz(val);
85
+ # else
86
+ return ZSTD_countLeadingZeros32_fallback(val);
87
+ # endif
88
+ }
89
+
90
+ MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val)
91
+ {
92
+ assert(val != 0);
93
+ # if defined(_MSC_VER) && defined(_WIN64)
94
+ # if STATIC_BMI2 == 1
95
+ return (unsigned)_tzcnt_u64(val);
96
+ # else
97
+ if (val != 0) {
98
+ unsigned long r;
99
+ _BitScanForward64(&r, val);
100
+ return (unsigned)r;
101
+ } else {
102
+ /* Should not reach this code path */
103
+ __assume(0);
104
+ }
105
+ # endif
106
+ # elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__)
107
+ return (unsigned)__builtin_ctzll(val);
108
+ # else
109
+ {
110
+ U32 mostSignificantWord = (U32)(val >> 32);
111
+ U32 leastSignificantWord = (U32)val;
112
+ if (leastSignificantWord == 0) {
113
+ return 32 + ZSTD_countTrailingZeros32(mostSignificantWord);
114
+ } else {
115
+ return ZSTD_countTrailingZeros32(leastSignificantWord);
116
+ }
117
+ }
118
+ # endif
119
+ }
120
+
121
+ MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val)
122
+ {
123
+ assert(val != 0);
124
+ # if defined(_MSC_VER) && defined(_WIN64)
125
+ # if STATIC_BMI2 == 1
126
+ return (unsigned)_lzcnt_u64(val);
127
+ # else
128
+ if (val != 0) {
129
+ unsigned long r;
130
+ _BitScanReverse64(&r, val);
131
+ return (unsigned)(63 - r);
132
+ } else {
133
+ /* Should not reach this code path */
134
+ __assume(0);
135
+ }
136
+ # endif
137
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
138
+ return (unsigned)(__builtin_clzll(val));
139
+ # else
140
+ {
141
+ U32 mostSignificantWord = (U32)(val >> 32);
142
+ U32 leastSignificantWord = (U32)val;
143
+ if (mostSignificantWord == 0) {
144
+ return 32 + ZSTD_countLeadingZeros32(leastSignificantWord);
145
+ } else {
146
+ return ZSTD_countLeadingZeros32(mostSignificantWord);
147
+ }
148
+ }
149
+ # endif
150
+ }
151
+
152
+ MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val)
153
+ {
154
+ if (MEM_isLittleEndian()) {
155
+ if (MEM_64bits()) {
156
+ return ZSTD_countTrailingZeros64((U64)val) >> 3;
157
+ } else {
158
+ return ZSTD_countTrailingZeros32((U32)val) >> 3;
159
+ }
160
+ } else { /* Big Endian CPU */
161
+ if (MEM_64bits()) {
162
+ return ZSTD_countLeadingZeros64((U64)val) >> 3;
163
+ } else {
164
+ return ZSTD_countLeadingZeros32((U32)val) >> 3;
165
+ }
166
+ }
167
+ }
168
+
169
+ MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
170
+ {
171
+ assert(val != 0);
172
+ return 31 - ZSTD_countLeadingZeros32(val);
173
+ }
174
+
175
+ /* ZSTD_rotateRight_*():
176
+ * Rotates a bitfield to the right by "count" bits.
177
+ * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts
178
+ */
179
+ MEM_STATIC
180
+ U64 ZSTD_rotateRight_U64(U64 const value, U32 count) {
181
+ assert(count < 64);
182
+ count &= 0x3F; /* for fickle pattern recognition */
183
+ return (value >> count) | (U64)(value << ((0U - count) & 0x3F));
184
+ }
185
+
186
+ MEM_STATIC
187
+ U32 ZSTD_rotateRight_U32(U32 const value, U32 count) {
188
+ assert(count < 32);
189
+ count &= 0x1F; /* for fickle pattern recognition */
190
+ return (value >> count) | (U32)(value << ((0U - count) & 0x1F));
191
+ }
192
+
193
+ MEM_STATIC
194
+ U16 ZSTD_rotateRight_U16(U16 const value, U32 count) {
195
+ assert(count < 16);
196
+ count &= 0x0F; /* for fickle pattern recognition */
197
+ return (value >> count) | (U16)(value << ((0U - count) & 0x0F));
198
+ }
199
+
200
+ #endif /* ZSTD_BITS_H */
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * bitstream
3
3
  * Part of FSE library
4
- * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -17,7 +17,6 @@
17
17
  #if defined (__cplusplus)
18
18
  extern "C" {
19
19
  #endif
20
-
21
20
  /*
22
21
  * This API consists of small unitary functions, which must be inlined for best performance.
23
22
  * Since link-time-optimization is not available for all compilers,
@@ -31,15 +30,18 @@ extern "C" {
31
30
  #include "compiler.h" /* UNLIKELY() */
32
31
  #include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */
33
32
  #include "error_private.h" /* error codes and messages */
33
+ #include "bits.h" /* ZSTD_highbit32 */
34
34
 
35
35
 
36
36
  /*=========================================
37
37
  * Target specific
38
38
  =========================================*/
39
- #if defined(__BMI__) && defined(__GNUC__)
40
- # include <immintrin.h> /* support for bextr (experimental) */
41
- #elif defined(__ICCARM__)
42
- # include <intrinsics.h>
39
+ #ifndef ZSTD_NO_INTRINSICS
40
+ # if (defined(__BMI__) || defined(__BMI2__)) && defined(__GNUC__)
41
+ # include <immintrin.h> /* support for bextr (experimental)/bzhi */
42
+ # elif defined(__ICCARM__)
43
+ # include <intrinsics.h>
44
+ # endif
43
45
  #endif
44
46
 
45
47
  #define STREAM_ACCUMULATOR_MIN_32 25
@@ -131,38 +133,6 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
131
133
  MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
132
134
  /* faster, but works only if nbBits >= 1 */
133
135
 
134
-
135
-
136
- /*-**************************************************************
137
- * Internal functions
138
- ****************************************************************/
139
- MEM_STATIC unsigned BIT_highbit32 (U32 val)
140
- {
141
- assert(val != 0);
142
- {
143
- # if defined(_MSC_VER) /* Visual */
144
- unsigned long r=0;
145
- return _BitScanReverse ( &r, val ) ? (unsigned)r : 0;
146
- # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
147
- return __builtin_clz (val) ^ 31;
148
- # elif defined(__ICCARM__) /* IAR Intrinsic */
149
- return 31 - __CLZ(val);
150
- # else /* Software version */
151
- static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
152
- 11, 14, 16, 18, 22, 25, 3, 30,
153
- 8, 12, 20, 28, 15, 17, 24, 7,
154
- 19, 27, 23, 6, 26, 5, 4, 31 };
155
- U32 v = val;
156
- v |= v >> 1;
157
- v |= v >> 2;
158
- v |= v >> 4;
159
- v |= v >> 8;
160
- v |= v >> 16;
161
- return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
162
- # endif
163
- }
164
- }
165
-
166
136
  /*===== Local Constants =====*/
167
137
  static const unsigned BIT_mask[] = {
168
138
  0, 1, 3, 7, 0xF, 0x1F,
@@ -192,16 +162,26 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
192
162
  return 0;
193
163
  }
194
164
 
165
+ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
166
+ {
167
+ #if defined(STATIC_BMI2) && STATIC_BMI2 == 1 && !defined(ZSTD_NO_INTRINSICS)
168
+ return _bzhi_u64(bitContainer, nbBits);
169
+ #else
170
+ assert(nbBits < BIT_MASK_SIZE);
171
+ return bitContainer & BIT_mask[nbBits];
172
+ #endif
173
+ }
174
+
195
175
  /*! BIT_addBits() :
196
176
  * can add up to 31 bits into `bitC`.
197
177
  * Note : does not check for register overflow ! */
198
178
  MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
199
179
  size_t value, unsigned nbBits)
200
180
  {
201
- MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32);
181
+ DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32);
202
182
  assert(nbBits < BIT_MASK_SIZE);
203
183
  assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
204
- bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
184
+ bitC->bitContainer |= BIT_getLowerBits(value, nbBits) << bitC->bitPos;
205
185
  bitC->bitPos += nbBits;
206
186
  }
207
187
 
@@ -271,7 +251,7 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
271
251
  */
272
252
  MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
273
253
  {
274
- if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
254
+ if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
275
255
 
276
256
  bitD->start = (const char*)srcBuffer;
277
257
  bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);
@@ -280,7 +260,7 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
280
260
  bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
281
261
  bitD->bitContainer = MEM_readLEST(bitD->ptr);
282
262
  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
283
- bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
263
+ bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
284
264
  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
285
265
  } else {
286
266
  bitD->ptr = bitD->start;
@@ -288,27 +268,27 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
288
268
  switch(srcSize)
289
269
  {
290
270
  case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
291
- /* fall-through */
271
+ ZSTD_FALLTHROUGH;
292
272
 
293
273
  case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
294
- /* fall-through */
274
+ ZSTD_FALLTHROUGH;
295
275
 
296
276
  case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
297
- /* fall-through */
277
+ ZSTD_FALLTHROUGH;
298
278
 
299
279
  case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
300
- /* fall-through */
280
+ ZSTD_FALLTHROUGH;
301
281
 
302
282
  case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
303
- /* fall-through */
283
+ ZSTD_FALLTHROUGH;
304
284
 
305
285
  case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
306
- /* fall-through */
286
+ ZSTD_FALLTHROUGH;
307
287
 
308
288
  default: break;
309
289
  }
310
290
  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
311
- bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
291
+ bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;
312
292
  if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
313
293
  }
314
294
  bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
@@ -317,23 +297,26 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
317
297
  return srcSize;
318
298
  }
319
299
 
320
- MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
300
+ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
321
301
  {
322
302
  return bitContainer >> start;
323
303
  }
324
304
 
325
- MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
305
+ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
326
306
  {
327
307
  U32 const regMask = sizeof(bitContainer)*8 - 1;
328
308
  /* if start > regMask, bitstream is corrupted, and result is undefined */
329
309
  assert(nbBits < BIT_MASK_SIZE);
310
+ /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better
311
+ * than accessing memory. When bmi2 instruction is not present, we consider
312
+ * such cpus old (pre-Haswell, 2013) and their performance is not of that
313
+ * importance.
314
+ */
315
+ #if defined(__x86_64__) || defined(_M_X86)
316
+ return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1);
317
+ #else
330
318
  return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
331
- }
332
-
333
- MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
334
- {
335
- assert(nbBits < BIT_MASK_SIZE);
336
- return bitContainer & BIT_mask[nbBits];
319
+ #endif
337
320
  }
338
321
 
339
322
  /*! BIT_lookBits() :
@@ -342,7 +325,7 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
342
325
  * On 32-bits, maxNbBits==24.
343
326
  * On 64-bits, maxNbBits==56.
344
327
  * @return : value extracted */
345
- MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
328
+ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
346
329
  {
347
330
  /* arbitrate between double-shift and shift+mask */
348
331
  #if 1
@@ -365,7 +348,7 @@ MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
365
348
  return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
366
349
  }
367
350
 
368
- MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
351
+ MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
369
352
  {
370
353
  bitD->bitsConsumed += nbBits;
371
354
  }
@@ -374,7 +357,7 @@ MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
374
357
  * Read (consume) next n bits from local register and update.
375
358
  * Pay attention to not read more than nbBits contained into local register.
376
359
  * @return : extracted value. */
377
- MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
360
+ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
378
361
  {
379
362
  size_t const value = BIT_lookBits(bitD, nbBits);
380
363
  BIT_skipBits(bitD, nbBits);
@@ -382,7 +365,7 @@ MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
382
365
  }
383
366
 
384
367
  /*! BIT_readBitsFast() :
385
- * unsafe version; only works only if nbBits >= 1 */
368
+ * unsafe version; only works if nbBits >= 1 */
386
369
  MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
387
370
  {
388
371
  size_t const value = BIT_lookBitsFast(bitD, nbBits);
@@ -413,7 +396,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
413
396
  * This function is safe, it guarantees it will not read beyond src buffer.
414
397
  * @return : status of `BIT_DStream_t` internal register.
415
398
  * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
416
- MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
399
+ MEM_STATIC FORCE_INLINE_ATTR BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
417
400
  {
418
401
  if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
419
402
  return BIT_DStream_overflow;