vibe_zstd 1.0.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.
- checksums.yaml +7 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +22 -0
- data/LICENSE.txt +21 -0
- data/README.md +978 -0
- data/Rakefile +20 -0
- data/benchmark/README.md +198 -0
- data/benchmark/compression_levels.rb +99 -0
- data/benchmark/context_reuse.rb +174 -0
- data/benchmark/decompression_speed_by_level.rb +65 -0
- data/benchmark/dictionary_training.rb +182 -0
- data/benchmark/dictionary_usage.rb +121 -0
- data/benchmark/for_readme.rb +157 -0
- data/benchmark/generate_fixture.rb +82 -0
- data/benchmark/helpers.rb +237 -0
- data/benchmark/multithreading.rb +105 -0
- data/benchmark/run_all.rb +150 -0
- data/benchmark/streaming.rb +154 -0
- data/ext/vibe_zstd/Makefile +270 -0
- data/ext/vibe_zstd/cctx.c +565 -0
- data/ext/vibe_zstd/dctx.c +493 -0
- data/ext/vibe_zstd/dict.c +587 -0
- data/ext/vibe_zstd/extconf.rb +52 -0
- data/ext/vibe_zstd/frames.c +132 -0
- data/ext/vibe_zstd/libzstd/LICENSE +30 -0
- data/ext/vibe_zstd/libzstd/common/allocations.h +55 -0
- data/ext/vibe_zstd/libzstd/common/bits.h +205 -0
- data/ext/vibe_zstd/libzstd/common/bitstream.h +454 -0
- data/ext/vibe_zstd/libzstd/common/compiler.h +464 -0
- data/ext/vibe_zstd/libzstd/common/cpu.h +249 -0
- data/ext/vibe_zstd/libzstd/common/debug.c +30 -0
- data/ext/vibe_zstd/libzstd/common/debug.h +107 -0
- data/ext/vibe_zstd/libzstd/common/entropy_common.c +340 -0
- data/ext/vibe_zstd/libzstd/common/error_private.c +64 -0
- data/ext/vibe_zstd/libzstd/common/error_private.h +158 -0
- data/ext/vibe_zstd/libzstd/common/fse.h +625 -0
- data/ext/vibe_zstd/libzstd/common/fse_decompress.c +315 -0
- data/ext/vibe_zstd/libzstd/common/huf.h +277 -0
- data/ext/vibe_zstd/libzstd/common/mem.h +422 -0
- data/ext/vibe_zstd/libzstd/common/pool.c +371 -0
- data/ext/vibe_zstd/libzstd/common/pool.h +81 -0
- data/ext/vibe_zstd/libzstd/common/portability_macros.h +171 -0
- data/ext/vibe_zstd/libzstd/common/threading.c +182 -0
- data/ext/vibe_zstd/libzstd/common/threading.h +142 -0
- data/ext/vibe_zstd/libzstd/common/xxhash.c +18 -0
- data/ext/vibe_zstd/libzstd/common/xxhash.h +7094 -0
- data/ext/vibe_zstd/libzstd/common/zstd_common.c +48 -0
- data/ext/vibe_zstd/libzstd/common/zstd_deps.h +123 -0
- data/ext/vibe_zstd/libzstd/common/zstd_internal.h +324 -0
- data/ext/vibe_zstd/libzstd/common/zstd_trace.h +156 -0
- data/ext/vibe_zstd/libzstd/compress/clevels.h +134 -0
- data/ext/vibe_zstd/libzstd/compress/fse_compress.c +625 -0
- data/ext/vibe_zstd/libzstd/compress/hist.c +191 -0
- data/ext/vibe_zstd/libzstd/compress/hist.h +82 -0
- data/ext/vibe_zstd/libzstd/compress/huf_compress.c +1464 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_compress.c +7843 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_compress_internal.h +1636 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_compress_literals.c +235 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_compress_literals.h +39 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_compress_sequences.c +442 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_compress_sequences.h +55 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_compress_superblock.c +688 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_compress_superblock.h +32 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_cwksp.h +765 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_double_fast.c +778 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_double_fast.h +42 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_fast.c +985 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_fast.h +30 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_lazy.c +2199 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_lazy.h +193 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_ldm.c +745 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_ldm.h +109 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_ldm_geartab.h +106 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_opt.c +1580 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_opt.h +72 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_preSplit.c +238 -0
- data/ext/vibe_zstd/libzstd/compress/zstd_preSplit.h +33 -0
- data/ext/vibe_zstd/libzstd/compress/zstdmt_compress.c +1923 -0
- data/ext/vibe_zstd/libzstd/compress/zstdmt_compress.h +102 -0
- data/ext/vibe_zstd/libzstd/decompress/huf_decompress.c +1944 -0
- data/ext/vibe_zstd/libzstd/decompress/huf_decompress_amd64.S +602 -0
- data/ext/vibe_zstd/libzstd/decompress/zstd_ddict.c +244 -0
- data/ext/vibe_zstd/libzstd/decompress/zstd_ddict.h +44 -0
- data/ext/vibe_zstd/libzstd/decompress/zstd_decompress.c +2410 -0
- data/ext/vibe_zstd/libzstd/decompress/zstd_decompress_block.c +2209 -0
- data/ext/vibe_zstd/libzstd/decompress/zstd_decompress_block.h +73 -0
- data/ext/vibe_zstd/libzstd/decompress/zstd_decompress_internal.h +240 -0
- data/ext/vibe_zstd/libzstd/deprecated/zbuff.h +214 -0
- data/ext/vibe_zstd/libzstd/deprecated/zbuff_common.c +26 -0
- data/ext/vibe_zstd/libzstd/deprecated/zbuff_compress.c +167 -0
- data/ext/vibe_zstd/libzstd/deprecated/zbuff_decompress.c +77 -0
- data/ext/vibe_zstd/libzstd/dictBuilder/cover.c +1302 -0
- data/ext/vibe_zstd/libzstd/dictBuilder/cover.h +152 -0
- data/ext/vibe_zstd/libzstd/dictBuilder/divsufsort.c +1913 -0
- data/ext/vibe_zstd/libzstd/dictBuilder/divsufsort.h +57 -0
- data/ext/vibe_zstd/libzstd/dictBuilder/fastcover.c +766 -0
- data/ext/vibe_zstd/libzstd/dictBuilder/zdict.c +1133 -0
- data/ext/vibe_zstd/libzstd/zdict.h +481 -0
- data/ext/vibe_zstd/libzstd/zstd.h +3198 -0
- data/ext/vibe_zstd/libzstd/zstd_errors.h +107 -0
- data/ext/vibe_zstd/streaming.c +410 -0
- data/ext/vibe_zstd/vibe_zstd.c +293 -0
- data/ext/vibe_zstd/vibe_zstd.h +56 -0
- data/ext/vibe_zstd/vibe_zstd_internal.h +27 -0
- data/lib/vibe_zstd/constants.rb +67 -0
- data/lib/vibe_zstd/version.rb +5 -0
- data/lib/vibe_zstd.rb +255 -0
- data/sig/vibe_zstd.rbs +76 -0
- metadata +179 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Frame utilities implementation for VibeZstd
|
|
2
|
+
#include "vibe_zstd_internal.h"
|
|
3
|
+
|
|
4
|
+
// VibeZstd.compress_bound(size)
|
|
5
|
+
static VALUE
|
|
6
|
+
vibe_zstd_compress_bound(VALUE self, VALUE size) {
|
|
7
|
+
size_t src_size = NUM2SIZET(size);
|
|
8
|
+
size_t bound = ZSTD_compressBound(src_size);
|
|
9
|
+
return SIZET2NUM(bound);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static VALUE
|
|
13
|
+
vibe_zstd_skippable_frame_p(VALUE self, VALUE data) {
|
|
14
|
+
(void)self;
|
|
15
|
+
StringValue(data);
|
|
16
|
+
unsigned result = ZSTD_isSkippableFrame(RSTRING_PTR(data), RSTRING_LEN(data));
|
|
17
|
+
return result ? Qtrue : Qfalse;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static VALUE
|
|
21
|
+
vibe_zstd_write_skippable_frame(int argc, VALUE *argv, VALUE self) {
|
|
22
|
+
(void)self;
|
|
23
|
+
VALUE data, options;
|
|
24
|
+
rb_scan_args(argc, argv, "11", &data, &options);
|
|
25
|
+
|
|
26
|
+
StringValue(data);
|
|
27
|
+
|
|
28
|
+
unsigned magic_variant = 0; // Default to 0
|
|
29
|
+
if (!NIL_P(options)) {
|
|
30
|
+
Check_Type(options, T_HASH);
|
|
31
|
+
VALUE magic_num = rb_hash_aref(options, ID2SYM(rb_intern("magic_number")));
|
|
32
|
+
if (!NIL_P(magic_num)) {
|
|
33
|
+
magic_variant = NUM2UINT(magic_num);
|
|
34
|
+
if (magic_variant > 15) {
|
|
35
|
+
rb_raise(rb_eArgError, "magic_number %u out of bounds (valid: 0-15)", magic_variant);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const char* src = RSTRING_PTR(data);
|
|
41
|
+
size_t src_size = RSTRING_LEN(data);
|
|
42
|
+
|
|
43
|
+
// Skippable frame structure: 4-byte magic (0x184D2A5X) + 4-byte size + content
|
|
44
|
+
// Decoders skip these frames, allowing custom metadata/padding
|
|
45
|
+
size_t frame_size = 8 + src_size;
|
|
46
|
+
VALUE result = rb_str_buf_new(frame_size);
|
|
47
|
+
|
|
48
|
+
size_t written = ZSTD_writeSkippableFrame(
|
|
49
|
+
RSTRING_PTR(result),
|
|
50
|
+
frame_size,
|
|
51
|
+
src,
|
|
52
|
+
src_size,
|
|
53
|
+
magic_variant
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
if (ZSTD_isError(written)) {
|
|
57
|
+
rb_raise(rb_eRuntimeError, "Failed to write skippable frame: %s", ZSTD_getErrorName(written));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
rb_str_set_len(result, written);
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static VALUE
|
|
65
|
+
vibe_zstd_read_skippable_frame(VALUE self, VALUE data) {
|
|
66
|
+
(void)self;
|
|
67
|
+
StringValue(data);
|
|
68
|
+
|
|
69
|
+
if (!ZSTD_isSkippableFrame(RSTRING_PTR(data), RSTRING_LEN(data))) {
|
|
70
|
+
rb_raise(rb_eArgError, "data is not a skippable frame (%zu bytes provided)", RSTRING_LEN(data));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const char* src = RSTRING_PTR(data);
|
|
74
|
+
size_t src_size = RSTRING_LEN(data);
|
|
75
|
+
|
|
76
|
+
// Content size is in bytes 4-7 (little-endian uint32)
|
|
77
|
+
if (src_size < 8) {
|
|
78
|
+
rb_raise(rb_eArgError, "skippable frame too small (%zu bytes, minimum 8 bytes required)", src_size);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
uint32_t content_size;
|
|
82
|
+
memcpy(&content_size, src + 4, 4);
|
|
83
|
+
|
|
84
|
+
VALUE result = rb_str_buf_new(content_size);
|
|
85
|
+
unsigned magic_variant;
|
|
86
|
+
|
|
87
|
+
size_t bytes_read = ZSTD_readSkippableFrame(
|
|
88
|
+
RSTRING_PTR(result),
|
|
89
|
+
content_size,
|
|
90
|
+
&magic_variant,
|
|
91
|
+
src,
|
|
92
|
+
src_size
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
if (ZSTD_isError(bytes_read)) {
|
|
96
|
+
rb_raise(rb_eRuntimeError, "Failed to read skippable frame: %s", ZSTD_getErrorName(bytes_read));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
rb_str_set_len(result, bytes_read);
|
|
100
|
+
|
|
101
|
+
// Return [content, magic_variant]
|
|
102
|
+
VALUE result_ary = rb_ary_new_capa(2);
|
|
103
|
+
rb_ary_push(result_ary, result);
|
|
104
|
+
rb_ary_push(result_ary, UINT2NUM(magic_variant));
|
|
105
|
+
return result_ary;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static VALUE
|
|
109
|
+
vibe_zstd_find_frame_compressed_size(VALUE self, VALUE data) {
|
|
110
|
+
(void)self;
|
|
111
|
+
StringValue(data);
|
|
112
|
+
|
|
113
|
+
// Returns compressed size of first complete frame (including header/checksum)
|
|
114
|
+
// Useful for splitting concatenated frames in multi-frame archives
|
|
115
|
+
size_t frame_size = ZSTD_findFrameCompressedSize(RSTRING_PTR(data), RSTRING_LEN(data));
|
|
116
|
+
|
|
117
|
+
if (ZSTD_isError(frame_size)) {
|
|
118
|
+
rb_raise(rb_eRuntimeError, "Failed to find frame size: %s", ZSTD_getErrorName(frame_size));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return SIZET2NUM(frame_size);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Module method initialization called from main Init_vibe_zstd
|
|
125
|
+
void
|
|
126
|
+
vibe_zstd_frames_init_module_methods(VALUE rb_mVibeZstd) {
|
|
127
|
+
rb_define_module_function(rb_mVibeZstd, "compress_bound", vibe_zstd_compress_bound, 1);
|
|
128
|
+
rb_define_module_function(rb_mVibeZstd, "skippable_frame?", vibe_zstd_skippable_frame_p, 1);
|
|
129
|
+
rb_define_module_function(rb_mVibeZstd, "write_skippable_frame", vibe_zstd_write_skippable_frame, -1);
|
|
130
|
+
rb_define_module_function(rb_mVibeZstd, "read_skippable_frame", vibe_zstd_read_skippable_frame, 1);
|
|
131
|
+
rb_define_module_function(rb_mVibeZstd, "find_frame_compressed_size", vibe_zstd_find_frame_compressed_size, 1);
|
|
132
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
BSD License
|
|
2
|
+
|
|
3
|
+
For Zstandard software
|
|
4
|
+
|
|
5
|
+
Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved.
|
|
6
|
+
|
|
7
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
8
|
+
are permitted provided that the following conditions are met:
|
|
9
|
+
|
|
10
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
11
|
+
list of conditions and the following disclaimer.
|
|
12
|
+
|
|
13
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
and/or other materials provided with the distribution.
|
|
16
|
+
|
|
17
|
+
* Neither the name Facebook, nor Meta, nor the names of its contributors may
|
|
18
|
+
be used to endorse or promote products derived from this software without
|
|
19
|
+
specific prior written permission.
|
|
20
|
+
|
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
22
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
23
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
24
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
25
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
26
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
27
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
28
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
29
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
30
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -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 "compiler.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,205 @@
|
|
|
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
|
|
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
|
+
__assume(0); /* Should not reach this code path */
|
|
41
|
+
}
|
|
42
|
+
# endif
|
|
43
|
+
#elif defined(__GNUC__) && (__GNUC__ >= 4)
|
|
44
|
+
return (unsigned)__builtin_ctz(val);
|
|
45
|
+
#elif defined(__ICCARM__)
|
|
46
|
+
return (unsigned)__builtin_ctz(val);
|
|
47
|
+
#else
|
|
48
|
+
return ZSTD_countTrailingZeros32_fallback(val);
|
|
49
|
+
#endif
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val)
|
|
53
|
+
{
|
|
54
|
+
assert(val != 0);
|
|
55
|
+
{
|
|
56
|
+
static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29,
|
|
57
|
+
11, 14, 16, 18, 22, 25, 3, 30,
|
|
58
|
+
8, 12, 20, 28, 15, 17, 24, 7,
|
|
59
|
+
19, 27, 23, 6, 26, 5, 4, 31};
|
|
60
|
+
val |= val >> 1;
|
|
61
|
+
val |= val >> 2;
|
|
62
|
+
val |= val >> 4;
|
|
63
|
+
val |= val >> 8;
|
|
64
|
+
val |= val >> 16;
|
|
65
|
+
return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val)
|
|
70
|
+
{
|
|
71
|
+
assert(val != 0);
|
|
72
|
+
#if defined(_MSC_VER)
|
|
73
|
+
# if STATIC_BMI2
|
|
74
|
+
return (unsigned)_lzcnt_u32(val);
|
|
75
|
+
# else
|
|
76
|
+
if (val != 0) {
|
|
77
|
+
unsigned long r;
|
|
78
|
+
_BitScanReverse(&r, val);
|
|
79
|
+
return (unsigned)(31 - r);
|
|
80
|
+
} else {
|
|
81
|
+
__assume(0); /* Should not reach this code path */
|
|
82
|
+
}
|
|
83
|
+
# endif
|
|
84
|
+
#elif defined(__GNUC__) && (__GNUC__ >= 4)
|
|
85
|
+
return (unsigned)__builtin_clz(val);
|
|
86
|
+
#elif defined(__ICCARM__)
|
|
87
|
+
return (unsigned)__builtin_clz(val);
|
|
88
|
+
#else
|
|
89
|
+
return ZSTD_countLeadingZeros32_fallback(val);
|
|
90
|
+
#endif
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val)
|
|
94
|
+
{
|
|
95
|
+
assert(val != 0);
|
|
96
|
+
#if defined(_MSC_VER) && defined(_WIN64)
|
|
97
|
+
# if STATIC_BMI2
|
|
98
|
+
return (unsigned)_tzcnt_u64(val);
|
|
99
|
+
# else
|
|
100
|
+
if (val != 0) {
|
|
101
|
+
unsigned long r;
|
|
102
|
+
_BitScanForward64(&r, val);
|
|
103
|
+
return (unsigned)r;
|
|
104
|
+
} else {
|
|
105
|
+
__assume(0); /* Should not reach this code path */
|
|
106
|
+
}
|
|
107
|
+
# endif
|
|
108
|
+
#elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__)
|
|
109
|
+
return (unsigned)__builtin_ctzll(val);
|
|
110
|
+
#elif defined(__ICCARM__)
|
|
111
|
+
return (unsigned)__builtin_ctzll(val);
|
|
112
|
+
#else
|
|
113
|
+
{
|
|
114
|
+
U32 mostSignificantWord = (U32)(val >> 32);
|
|
115
|
+
U32 leastSignificantWord = (U32)val;
|
|
116
|
+
if (leastSignificantWord == 0) {
|
|
117
|
+
return 32 + ZSTD_countTrailingZeros32(mostSignificantWord);
|
|
118
|
+
} else {
|
|
119
|
+
return ZSTD_countTrailingZeros32(leastSignificantWord);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
#endif
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val)
|
|
126
|
+
{
|
|
127
|
+
assert(val != 0);
|
|
128
|
+
#if defined(_MSC_VER) && defined(_WIN64)
|
|
129
|
+
# if STATIC_BMI2
|
|
130
|
+
return (unsigned)_lzcnt_u64(val);
|
|
131
|
+
# else
|
|
132
|
+
if (val != 0) {
|
|
133
|
+
unsigned long r;
|
|
134
|
+
_BitScanReverse64(&r, val);
|
|
135
|
+
return (unsigned)(63 - r);
|
|
136
|
+
} else {
|
|
137
|
+
__assume(0); /* Should not reach this code path */
|
|
138
|
+
}
|
|
139
|
+
# endif
|
|
140
|
+
#elif defined(__GNUC__) && (__GNUC__ >= 4)
|
|
141
|
+
return (unsigned)(__builtin_clzll(val));
|
|
142
|
+
#elif defined(__ICCARM__)
|
|
143
|
+
return (unsigned)(__builtin_clzll(val));
|
|
144
|
+
#else
|
|
145
|
+
{
|
|
146
|
+
U32 mostSignificantWord = (U32)(val >> 32);
|
|
147
|
+
U32 leastSignificantWord = (U32)val;
|
|
148
|
+
if (mostSignificantWord == 0) {
|
|
149
|
+
return 32 + ZSTD_countLeadingZeros32(leastSignificantWord);
|
|
150
|
+
} else {
|
|
151
|
+
return ZSTD_countLeadingZeros32(mostSignificantWord);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
#endif
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val)
|
|
158
|
+
{
|
|
159
|
+
if (MEM_isLittleEndian()) {
|
|
160
|
+
if (MEM_64bits()) {
|
|
161
|
+
return ZSTD_countTrailingZeros64((U64)val) >> 3;
|
|
162
|
+
} else {
|
|
163
|
+
return ZSTD_countTrailingZeros32((U32)val) >> 3;
|
|
164
|
+
}
|
|
165
|
+
} else { /* Big Endian CPU */
|
|
166
|
+
if (MEM_64bits()) {
|
|
167
|
+
return ZSTD_countLeadingZeros64((U64)val) >> 3;
|
|
168
|
+
} else {
|
|
169
|
+
return ZSTD_countLeadingZeros32((U32)val) >> 3;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
|
|
175
|
+
{
|
|
176
|
+
assert(val != 0);
|
|
177
|
+
return 31 - ZSTD_countLeadingZeros32(val);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* ZSTD_rotateRight_*():
|
|
181
|
+
* Rotates a bitfield to the right by "count" bits.
|
|
182
|
+
* https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts
|
|
183
|
+
*/
|
|
184
|
+
MEM_STATIC
|
|
185
|
+
U64 ZSTD_rotateRight_U64(U64 const value, U32 count) {
|
|
186
|
+
assert(count < 64);
|
|
187
|
+
count &= 0x3F; /* for fickle pattern recognition */
|
|
188
|
+
return (value >> count) | (U64)(value << ((0U - count) & 0x3F));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
MEM_STATIC
|
|
192
|
+
U32 ZSTD_rotateRight_U32(U32 const value, U32 count) {
|
|
193
|
+
assert(count < 32);
|
|
194
|
+
count &= 0x1F; /* for fickle pattern recognition */
|
|
195
|
+
return (value >> count) | (U32)(value << ((0U - count) & 0x1F));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
MEM_STATIC
|
|
199
|
+
U16 ZSTD_rotateRight_U16(U16 const value, U32 count) {
|
|
200
|
+
assert(count < 16);
|
|
201
|
+
count &= 0x0F; /* for fickle pattern recognition */
|
|
202
|
+
return (value >> count) | (U16)(value << ((0U - count) & 0x0F));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
#endif /* ZSTD_BITS_H */
|