zstd-ruby 1.4.0.0 → 1.4.9.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 +4 -4
- data/.github/workflows/ruby.yml +35 -0
- data/README.md +2 -2
- data/ext/zstdruby/libzstd/Makefile +274 -107
- data/ext/zstdruby/libzstd/README.md +75 -16
- data/ext/zstdruby/libzstd/common/bitstream.h +59 -51
- data/ext/zstdruby/libzstd/common/compiler.h +154 -5
- data/ext/zstdruby/libzstd/common/cpu.h +1 -3
- data/ext/zstdruby/libzstd/common/debug.c +11 -31
- data/ext/zstdruby/libzstd/common/debug.h +22 -49
- data/ext/zstdruby/libzstd/common/entropy_common.c +201 -75
- data/ext/zstdruby/libzstd/common/error_private.c +3 -1
- data/ext/zstdruby/libzstd/common/error_private.h +7 -3
- data/ext/zstdruby/libzstd/common/fse.h +50 -42
- data/ext/zstdruby/libzstd/common/fse_decompress.c +134 -50
- data/ext/zstdruby/libzstd/common/huf.h +41 -38
- data/ext/zstdruby/libzstd/common/mem.h +68 -22
- data/ext/zstdruby/libzstd/common/pool.c +30 -20
- data/ext/zstdruby/libzstd/common/pool.h +3 -3
- data/ext/zstdruby/libzstd/common/threading.c +51 -4
- data/ext/zstdruby/libzstd/common/threading.h +36 -4
- data/ext/zstdruby/libzstd/common/xxhash.c +39 -89
- data/ext/zstdruby/libzstd/common/xxhash.h +12 -32
- data/ext/zstdruby/libzstd/common/zstd_common.c +10 -10
- data/ext/zstdruby/libzstd/common/zstd_deps.h +111 -0
- data/ext/zstdruby/libzstd/common/zstd_errors.h +3 -1
- data/ext/zstdruby/libzstd/common/zstd_internal.h +231 -72
- data/ext/zstdruby/libzstd/common/zstd_trace.c +42 -0
- data/ext/zstdruby/libzstd/common/zstd_trace.h +152 -0
- data/ext/zstdruby/libzstd/compress/fse_compress.c +47 -63
- data/ext/zstdruby/libzstd/compress/hist.c +41 -63
- data/ext/zstdruby/libzstd/compress/hist.h +13 -33
- data/ext/zstdruby/libzstd/compress/huf_compress.c +288 -172
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +2504 -1626
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +446 -85
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +158 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +29 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +433 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +54 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +849 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +32 -0
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +561 -0
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +82 -60
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +106 -80
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +411 -105
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +21 -1
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +296 -207
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +14 -3
- data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +103 -0
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +260 -148
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +153 -440
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +29 -110
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +356 -238
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +20 -16
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +3 -3
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +641 -238
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +600 -371
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +8 -5
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +40 -9
- data/ext/zstdruby/libzstd/deprecated/zbuff.h +9 -8
- data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +2 -2
- data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
- data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +197 -78
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +52 -7
- data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +84 -66
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +58 -36
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +60 -31
- data/ext/zstdruby/libzstd/dll/example/Makefile +2 -1
- data/ext/zstdruby/libzstd/dll/example/README.md +16 -22
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +8 -4
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +115 -111
- data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +28 -14
- data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +28 -14
- data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +36 -19
- data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +122 -107
- data/ext/zstdruby/libzstd/legacy/zstd_v05.h +2 -2
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +29 -23
- data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +34 -24
- data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -1
- data/ext/zstdruby/libzstd/libzstd.pc.in +2 -1
- data/ext/zstdruby/libzstd/zstd.h +655 -118
- data/lib/zstd-ruby/version.rb +1 -1
- data/zstd-ruby.gemspec +1 -1
- metadata +20 -10
- data/.travis.yml +0 -14
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2016-
|
|
2
|
+
* Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
7
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.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
#ifndef ZSTD_LDM_H
|
|
@@ -15,7 +16,7 @@ extern "C" {
|
|
|
15
16
|
#endif
|
|
16
17
|
|
|
17
18
|
#include "zstd_compress_internal.h" /* ldmParams_t, U32 */
|
|
18
|
-
#include "zstd.h" /* ZSTD_CCtx, size_t */
|
|
19
|
+
#include "../zstd.h" /* ZSTD_CCtx, size_t */
|
|
19
20
|
|
|
20
21
|
/*-*************************************
|
|
21
22
|
* Long distance matching
|
|
@@ -23,6 +24,10 @@ extern "C" {
|
|
|
23
24
|
|
|
24
25
|
#define ZSTD_LDM_DEFAULT_WINDOW_LOG ZSTD_WINDOWLOG_LIMIT_DEFAULT
|
|
25
26
|
|
|
27
|
+
void ZSTD_ldm_fillHashTable(
|
|
28
|
+
ldmState_t* state, const BYTE* ip,
|
|
29
|
+
const BYTE* iend, ldmParams_t const* params);
|
|
30
|
+
|
|
26
31
|
/**
|
|
27
32
|
* ZSTD_ldm_generateSequences():
|
|
28
33
|
*
|
|
@@ -68,11 +73,17 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
|
|
68
73
|
*
|
|
69
74
|
* Skip past `srcSize` bytes worth of sequences in `rawSeqStore`.
|
|
70
75
|
* Avoids emitting matches less than `minMatch` bytes.
|
|
71
|
-
* Must be called for data
|
|
76
|
+
* Must be called for data that is not passed to ZSTD_ldm_blockCompress().
|
|
72
77
|
*/
|
|
73
78
|
void ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize,
|
|
74
79
|
U32 const minMatch);
|
|
75
80
|
|
|
81
|
+
/* ZSTD_ldm_skipRawSeqStoreBytes():
|
|
82
|
+
* Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'.
|
|
83
|
+
* Not to be used in conjunction with ZSTD_ldm_skipSequences().
|
|
84
|
+
* Must be called for data with is not passed to ZSTD_ldm_blockCompress().
|
|
85
|
+
*/
|
|
86
|
+
void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes);
|
|
76
87
|
|
|
77
88
|
/** ZSTD_ldm_getTableSize() :
|
|
78
89
|
* Estimate the space needed for long distance matching tables or 0 if LDM is
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
|
|
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_LDM_GEARTAB_H
|
|
12
|
+
#define ZSTD_LDM_GEARTAB_H
|
|
13
|
+
|
|
14
|
+
static U64 ZSTD_ldm_gearTab[256] = {
|
|
15
|
+
0xf5b8f72c5f77775c, 0x84935f266b7ac412, 0xb647ada9ca730ccc,
|
|
16
|
+
0xb065bb4b114fb1de, 0x34584e7e8c3a9fd0, 0x4e97e17c6ae26b05,
|
|
17
|
+
0x3a03d743bc99a604, 0xcecd042422c4044f, 0x76de76c58524259e,
|
|
18
|
+
0x9c8528f65badeaca, 0x86563706e2097529, 0x2902475fa375d889,
|
|
19
|
+
0xafb32a9739a5ebe6, 0xce2714da3883e639, 0x21eaf821722e69e,
|
|
20
|
+
0x37b628620b628, 0x49a8d455d88caf5, 0x8556d711e6958140,
|
|
21
|
+
0x4f7ae74fc605c1f, 0x829f0c3468bd3a20, 0x4ffdc885c625179e,
|
|
22
|
+
0x8473de048a3daf1b, 0x51008822b05646b2, 0x69d75d12b2d1cc5f,
|
|
23
|
+
0x8c9d4a19159154bc, 0xc3cc10f4abbd4003, 0xd06ddc1cecb97391,
|
|
24
|
+
0xbe48e6e7ed80302e, 0x3481db31cee03547, 0xacc3f67cdaa1d210,
|
|
25
|
+
0x65cb771d8c7f96cc, 0x8eb27177055723dd, 0xc789950d44cd94be,
|
|
26
|
+
0x934feadc3700b12b, 0x5e485f11edbdf182, 0x1e2e2a46fd64767a,
|
|
27
|
+
0x2969ca71d82efa7c, 0x9d46e9935ebbba2e, 0xe056b67e05e6822b,
|
|
28
|
+
0x94d73f55739d03a0, 0xcd7010bdb69b5a03, 0x455ef9fcd79b82f4,
|
|
29
|
+
0x869cb54a8749c161, 0x38d1a4fa6185d225, 0xb475166f94bbe9bb,
|
|
30
|
+
0xa4143548720959f1, 0x7aed4780ba6b26ba, 0xd0ce264439e02312,
|
|
31
|
+
0x84366d746078d508, 0xa8ce973c72ed17be, 0x21c323a29a430b01,
|
|
32
|
+
0x9962d617e3af80ee, 0xab0ce91d9c8cf75b, 0x530e8ee6d19a4dbc,
|
|
33
|
+
0x2ef68c0cf53f5d72, 0xc03a681640a85506, 0x496e4e9f9c310967,
|
|
34
|
+
0x78580472b59b14a0, 0x273824c23b388577, 0x66bf923ad45cb553,
|
|
35
|
+
0x47ae1a5a2492ba86, 0x35e304569e229659, 0x4765182a46870b6f,
|
|
36
|
+
0x6cbab625e9099412, 0xddac9a2e598522c1, 0x7172086e666624f2,
|
|
37
|
+
0xdf5003ca503b7837, 0x88c0c1db78563d09, 0x58d51865acfc289d,
|
|
38
|
+
0x177671aec65224f1, 0xfb79d8a241e967d7, 0x2be1e101cad9a49a,
|
|
39
|
+
0x6625682f6e29186b, 0x399553457ac06e50, 0x35dffb4c23abb74,
|
|
40
|
+
0x429db2591f54aade, 0xc52802a8037d1009, 0x6acb27381f0b25f3,
|
|
41
|
+
0xf45e2551ee4f823b, 0x8b0ea2d99580c2f7, 0x3bed519cbcb4e1e1,
|
|
42
|
+
0xff452823dbb010a, 0x9d42ed614f3dd267, 0x5b9313c06257c57b,
|
|
43
|
+
0xa114b8008b5e1442, 0xc1fe311c11c13d4b, 0x66e8763ea34c5568,
|
|
44
|
+
0x8b982af1c262f05d, 0xee8876faaa75fbb7, 0x8a62a4d0d172bb2a,
|
|
45
|
+
0xc13d94a3b7449a97, 0x6dbbba9dc15d037c, 0xc786101f1d92e0f1,
|
|
46
|
+
0xd78681a907a0b79b, 0xf61aaf2962c9abb9, 0x2cfd16fcd3cb7ad9,
|
|
47
|
+
0x868c5b6744624d21, 0x25e650899c74ddd7, 0xba042af4a7c37463,
|
|
48
|
+
0x4eb1a539465a3eca, 0xbe09dbf03b05d5ca, 0x774e5a362b5472ba,
|
|
49
|
+
0x47a1221229d183cd, 0x504b0ca18ef5a2df, 0xdffbdfbde2456eb9,
|
|
50
|
+
0x46cd2b2fbee34634, 0xf2aef8fe819d98c3, 0x357f5276d4599d61,
|
|
51
|
+
0x24a5483879c453e3, 0x88026889192b4b9, 0x28da96671782dbec,
|
|
52
|
+
0x4ef37c40588e9aaa, 0x8837b90651bc9fb3, 0xc164f741d3f0e5d6,
|
|
53
|
+
0xbc135a0a704b70ba, 0x69cd868f7622ada, 0xbc37ba89e0b9c0ab,
|
|
54
|
+
0x47c14a01323552f6, 0x4f00794bacee98bb, 0x7107de7d637a69d5,
|
|
55
|
+
0x88af793bb6f2255e, 0xf3c6466b8799b598, 0xc288c616aa7f3b59,
|
|
56
|
+
0x81ca63cf42fca3fd, 0x88d85ace36a2674b, 0xd056bd3792389e7,
|
|
57
|
+
0xe55c396c4e9dd32d, 0xbefb504571e6c0a6, 0x96ab32115e91e8cc,
|
|
58
|
+
0xbf8acb18de8f38d1, 0x66dae58801672606, 0x833b6017872317fb,
|
|
59
|
+
0xb87c16f2d1c92864, 0xdb766a74e58b669c, 0x89659f85c61417be,
|
|
60
|
+
0xc8daad856011ea0c, 0x76a4b565b6fe7eae, 0xa469d085f6237312,
|
|
61
|
+
0xaaf0365683a3e96c, 0x4dbb746f8424f7b8, 0x638755af4e4acc1,
|
|
62
|
+
0x3d7807f5bde64486, 0x17be6d8f5bbb7639, 0x903f0cd44dc35dc,
|
|
63
|
+
0x67b672eafdf1196c, 0xa676ff93ed4c82f1, 0x521d1004c5053d9d,
|
|
64
|
+
0x37ba9ad09ccc9202, 0x84e54d297aacfb51, 0xa0b4b776a143445,
|
|
65
|
+
0x820d471e20b348e, 0x1874383cb83d46dc, 0x97edeec7a1efe11c,
|
|
66
|
+
0xb330e50b1bdc42aa, 0x1dd91955ce70e032, 0xa514cdb88f2939d5,
|
|
67
|
+
0x2791233fd90db9d3, 0x7b670a4cc50f7a9b, 0x77c07d2a05c6dfa5,
|
|
68
|
+
0xe3778b6646d0a6fa, 0xb39c8eda47b56749, 0x933ed448addbef28,
|
|
69
|
+
0xaf846af6ab7d0bf4, 0xe5af208eb666e49, 0x5e6622f73534cd6a,
|
|
70
|
+
0x297daeca42ef5b6e, 0x862daef3d35539a6, 0xe68722498f8e1ea9,
|
|
71
|
+
0x981c53093dc0d572, 0xfa09b0bfbf86fbf5, 0x30b1e96166219f15,
|
|
72
|
+
0x70e7d466bdc4fb83, 0x5a66736e35f2a8e9, 0xcddb59d2b7c1baef,
|
|
73
|
+
0xd6c7d247d26d8996, 0xea4e39eac8de1ba3, 0x539c8bb19fa3aff2,
|
|
74
|
+
0x9f90e4c5fd508d8, 0xa34e5956fbaf3385, 0x2e2f8e151d3ef375,
|
|
75
|
+
0x173691e9b83faec1, 0xb85a8d56bf016379, 0x8382381267408ae3,
|
|
76
|
+
0xb90f901bbdc0096d, 0x7c6ad32933bcec65, 0x76bb5e2f2c8ad595,
|
|
77
|
+
0x390f851a6cf46d28, 0xc3e6064da1c2da72, 0xc52a0c101cfa5389,
|
|
78
|
+
0xd78eaf84a3fbc530, 0x3781b9e2288b997e, 0x73c2f6dea83d05c4,
|
|
79
|
+
0x4228e364c5b5ed7, 0x9d7a3edf0da43911, 0x8edcfeda24686756,
|
|
80
|
+
0x5e7667a7b7a9b3a1, 0x4c4f389fa143791d, 0xb08bc1023da7cddc,
|
|
81
|
+
0x7ab4be3ae529b1cc, 0x754e6132dbe74ff9, 0x71635442a839df45,
|
|
82
|
+
0x2f6fb1643fbe52de, 0x961e0a42cf7a8177, 0xf3b45d83d89ef2ea,
|
|
83
|
+
0xee3de4cf4a6e3e9b, 0xcd6848542c3295e7, 0xe4cee1664c78662f,
|
|
84
|
+
0x9947548b474c68c4, 0x25d73777a5ed8b0b, 0xc915b1d636b7fc,
|
|
85
|
+
0x21c2ba75d9b0d2da, 0x5f6b5dcf608a64a1, 0xdcf333255ff9570c,
|
|
86
|
+
0x633b922418ced4ee, 0xc136dde0b004b34a, 0x58cc83b05d4b2f5a,
|
|
87
|
+
0x5eb424dda28e42d2, 0x62df47369739cd98, 0xb4e0b42485e4ce17,
|
|
88
|
+
0x16e1f0c1f9a8d1e7, 0x8ec3916707560ebf, 0x62ba6e2df2cc9db3,
|
|
89
|
+
0xcbf9f4ff77d83a16, 0x78d9d7d07d2bbcc4, 0xef554ce1e02c41f4,
|
|
90
|
+
0x8d7581127eccf94d, 0xa9b53336cb3c8a05, 0x38c42c0bf45c4f91,
|
|
91
|
+
0x640893cdf4488863, 0x80ec34bc575ea568, 0x39f324f5b48eaa40,
|
|
92
|
+
0xe9d9ed1f8eff527f, 0x9224fc058cc5a214, 0xbaba00b04cfe7741,
|
|
93
|
+
0x309a9f120fcf52af, 0xa558f3ec65626212, 0x424bec8b7adabe2f,
|
|
94
|
+
0x41622513a6aea433, 0xb88da2d5324ca798, 0xd287733b245528a4,
|
|
95
|
+
0x9a44697e6d68aec3, 0x7b1093be2f49bb28, 0x50bbec632e3d8aad,
|
|
96
|
+
0x6cd90723e1ea8283, 0x897b9e7431b02bf3, 0x219efdcb338a7047,
|
|
97
|
+
0x3b0311f0a27c0656, 0xdb17bf91c0db96e7, 0x8cd4fd6b4e85a5b2,
|
|
98
|
+
0xfab071054ba6409d, 0x40d6fe831fa9dfd9, 0xaf358debad7d791e,
|
|
99
|
+
0xeb8d0e25a65e3e58, 0xbbcbd3df14e08580, 0xcf751f27ecdab2b,
|
|
100
|
+
0x2b4da14f2613d8f4
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
#endif /* ZSTD_LDM_GEARTAB_H */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2016-
|
|
2
|
+
* Copyright (c) 2016-2021, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -249,40 +249,6 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP
|
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
/* ZSTD_litLengthContribution() :
|
|
253
|
-
* @return ( cost(litlength) - cost(0) )
|
|
254
|
-
* this value can then be added to rawLiteralsCost()
|
|
255
|
-
* to provide a cost which is directly comparable to a match ending at same position */
|
|
256
|
-
static int ZSTD_litLengthContribution(U32 const litLength, const optState_t* const optPtr, int optLevel)
|
|
257
|
-
{
|
|
258
|
-
if (optPtr->priceType >= zop_predef) return WEIGHT(litLength, optLevel);
|
|
259
|
-
|
|
260
|
-
/* dynamic statistics */
|
|
261
|
-
{ U32 const llCode = ZSTD_LLcode(litLength);
|
|
262
|
-
int const contribution = (LL_bits[llCode] * BITCOST_MULTIPLIER)
|
|
263
|
-
+ WEIGHT(optPtr->litLengthFreq[0], optLevel) /* note: log2litLengthSum cancel out */
|
|
264
|
-
- WEIGHT(optPtr->litLengthFreq[llCode], optLevel);
|
|
265
|
-
#if 1
|
|
266
|
-
return contribution;
|
|
267
|
-
#else
|
|
268
|
-
return MAX(0, contribution); /* sometimes better, sometimes not ... */
|
|
269
|
-
#endif
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/* ZSTD_literalsContribution() :
|
|
274
|
-
* creates a fake cost for the literals part of a sequence
|
|
275
|
-
* which can be compared to the ending cost of a match
|
|
276
|
-
* should a new match start at this position */
|
|
277
|
-
static int ZSTD_literalsContribution(const BYTE* const literals, U32 const litLength,
|
|
278
|
-
const optState_t* const optPtr,
|
|
279
|
-
int optLevel)
|
|
280
|
-
{
|
|
281
|
-
int const contribution = ZSTD_rawLiteralsCost(literals, litLength, optPtr, optLevel)
|
|
282
|
-
+ ZSTD_litLengthContribution(litLength, optPtr, optLevel);
|
|
283
|
-
return contribution;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
252
|
/* ZSTD_getMatchPrice() :
|
|
287
253
|
* Provides the cost of the match part (offset + matchLength) of a sequence
|
|
288
254
|
* Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence.
|
|
@@ -372,13 +338,15 @@ MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
|
|
|
372
338
|
|
|
373
339
|
/* Update hashTable3 up to ip (excluded)
|
|
374
340
|
Assumption : always within prefix (i.e. not within extDict) */
|
|
375
|
-
static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms,
|
|
341
|
+
static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms,
|
|
342
|
+
U32* nextToUpdate3,
|
|
343
|
+
const BYTE* const ip)
|
|
376
344
|
{
|
|
377
345
|
U32* const hashTable3 = ms->hashTable3;
|
|
378
346
|
U32 const hashLog3 = ms->hashLog3;
|
|
379
347
|
const BYTE* const base = ms->window.base;
|
|
380
|
-
U32 idx =
|
|
381
|
-
U32 const target =
|
|
348
|
+
U32 idx = *nextToUpdate3;
|
|
349
|
+
U32 const target = (U32)(ip - base);
|
|
382
350
|
size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3);
|
|
383
351
|
assert(hashLog3 > 0);
|
|
384
352
|
|
|
@@ -387,6 +355,7 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, const BYTE*
|
|
|
387
355
|
idx++;
|
|
388
356
|
}
|
|
389
357
|
|
|
358
|
+
*nextToUpdate3 = target;
|
|
390
359
|
return hashTable3[hash3];
|
|
391
360
|
}
|
|
392
361
|
|
|
@@ -417,32 +386,32 @@ static U32 ZSTD_insertBt1(
|
|
|
417
386
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
|
418
387
|
const BYTE* const prefixStart = base + dictLimit;
|
|
419
388
|
const BYTE* match;
|
|
420
|
-
const U32
|
|
421
|
-
const U32 btLow = btMask >=
|
|
422
|
-
U32* smallerPtr = bt + 2*(
|
|
389
|
+
const U32 curr = (U32)(ip-base);
|
|
390
|
+
const U32 btLow = btMask >= curr ? 0 : curr - btMask;
|
|
391
|
+
U32* smallerPtr = bt + 2*(curr&btMask);
|
|
423
392
|
U32* largerPtr = smallerPtr + 1;
|
|
424
393
|
U32 dummy32; /* to be nullified at the end */
|
|
425
394
|
U32 const windowLow = ms->window.lowLimit;
|
|
426
|
-
U32 matchEndIdx =
|
|
395
|
+
U32 matchEndIdx = curr+8+1;
|
|
427
396
|
size_t bestLength = 8;
|
|
428
397
|
U32 nbCompares = 1U << cParams->searchLog;
|
|
429
398
|
#ifdef ZSTD_C_PREDICT
|
|
430
|
-
U32 predictedSmall = *(bt + 2*((
|
|
431
|
-
U32 predictedLarge = *(bt + 2*((
|
|
399
|
+
U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0);
|
|
400
|
+
U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1);
|
|
432
401
|
predictedSmall += (predictedSmall>0);
|
|
433
402
|
predictedLarge += (predictedLarge>0);
|
|
434
403
|
#endif /* ZSTD_C_PREDICT */
|
|
435
404
|
|
|
436
|
-
DEBUGLOG(8, "ZSTD_insertBt1 (%u)",
|
|
405
|
+
DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr);
|
|
437
406
|
|
|
438
407
|
assert(ip <= iend-8); /* required for h calculation */
|
|
439
|
-
hashTable[h] =
|
|
408
|
+
hashTable[h] = curr; /* Update Hash Table */
|
|
440
409
|
|
|
441
410
|
assert(windowLow > 0);
|
|
442
411
|
while (nbCompares-- && (matchIndex >= windowLow)) {
|
|
443
412
|
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
|
444
413
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
|
445
|
-
assert(matchIndex <
|
|
414
|
+
assert(matchIndex < curr);
|
|
446
415
|
|
|
447
416
|
#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
|
|
448
417
|
const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
|
|
@@ -503,9 +472,11 @@ static U32 ZSTD_insertBt1(
|
|
|
503
472
|
} }
|
|
504
473
|
|
|
505
474
|
*smallerPtr = *largerPtr = 0;
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
475
|
+
{ U32 positions = 0;
|
|
476
|
+
if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384)); /* speed optimization */
|
|
477
|
+
assert(matchEndIdx > curr + 8);
|
|
478
|
+
return MAX(positions, matchEndIdx - (curr + 8));
|
|
479
|
+
}
|
|
509
480
|
}
|
|
510
481
|
|
|
511
482
|
FORCE_INLINE_TEMPLATE
|
|
@@ -520,8 +491,13 @@ void ZSTD_updateTree_internal(
|
|
|
520
491
|
DEBUGLOG(6, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)",
|
|
521
492
|
idx, target, dictMode);
|
|
522
493
|
|
|
523
|
-
while(idx < target)
|
|
524
|
-
|
|
494
|
+
while(idx < target) {
|
|
495
|
+
U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, mls, dictMode == ZSTD_extDict);
|
|
496
|
+
assert(idx < (U32)(idx + forward));
|
|
497
|
+
idx += forward;
|
|
498
|
+
}
|
|
499
|
+
assert((size_t)(ip - base) <= (size_t)(U32)(-1));
|
|
500
|
+
assert((size_t)(iend - base) <= (size_t)(U32)(-1));
|
|
525
501
|
ms->nextToUpdate = target;
|
|
526
502
|
}
|
|
527
503
|
|
|
@@ -531,18 +507,19 @@ void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) {
|
|
|
531
507
|
|
|
532
508
|
FORCE_INLINE_TEMPLATE
|
|
533
509
|
U32 ZSTD_insertBtAndGetAllMatches (
|
|
510
|
+
ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */
|
|
534
511
|
ZSTD_matchState_t* ms,
|
|
512
|
+
U32* nextToUpdate3,
|
|
535
513
|
const BYTE* const ip, const BYTE* const iLimit, const ZSTD_dictMode_e dictMode,
|
|
536
|
-
U32 rep[ZSTD_REP_NUM],
|
|
514
|
+
const U32 rep[ZSTD_REP_NUM],
|
|
537
515
|
U32 const ll0, /* tells if associated literal length is 0 or not. This value must be 0 or 1 */
|
|
538
|
-
ZSTD_match_t* matches,
|
|
539
516
|
const U32 lengthToBeat,
|
|
540
517
|
U32 const mls /* template */)
|
|
541
518
|
{
|
|
542
519
|
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
|
543
520
|
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
|
|
544
521
|
const BYTE* const base = ms->window.base;
|
|
545
|
-
U32 const
|
|
522
|
+
U32 const curr = (U32)(ip-base);
|
|
546
523
|
U32 const hashLog = cParams->hashLog;
|
|
547
524
|
U32 const minMatch = (mls==3) ? 3 : 4;
|
|
548
525
|
U32* const hashTable = ms->hashTable;
|
|
@@ -556,12 +533,12 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
556
533
|
U32 const dictLimit = ms->window.dictLimit;
|
|
557
534
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
|
558
535
|
const BYTE* const prefixStart = base + dictLimit;
|
|
559
|
-
U32 const btLow = btMask >=
|
|
560
|
-
U32 const windowLow = ms->
|
|
536
|
+
U32 const btLow = (btMask >= curr) ? 0 : curr - btMask;
|
|
537
|
+
U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog);
|
|
561
538
|
U32 const matchLow = windowLow ? windowLow : 1;
|
|
562
|
-
U32* smallerPtr = bt + 2*(
|
|
563
|
-
U32* largerPtr = bt + 2*(
|
|
564
|
-
U32 matchEndIdx =
|
|
539
|
+
U32* smallerPtr = bt + 2*(curr&btMask);
|
|
540
|
+
U32* largerPtr = bt + 2*(curr&btMask) + 1;
|
|
541
|
+
U32 matchEndIdx = curr+8+1; /* farthest referenced position of any match => detects repetitive patterns */
|
|
565
542
|
U32 dummy32; /* to be nullified at the end */
|
|
566
543
|
U32 mnum = 0;
|
|
567
544
|
U32 nbCompares = 1U << cParams->searchLog;
|
|
@@ -580,7 +557,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
580
557
|
U32 const dmsBtLow = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit;
|
|
581
558
|
|
|
582
559
|
size_t bestLength = lengthToBeat-1;
|
|
583
|
-
DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u",
|
|
560
|
+
DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", curr);
|
|
584
561
|
|
|
585
562
|
/* check repCode */
|
|
586
563
|
assert(ll0 <= 1); /* necessarily 1 or 0 */
|
|
@@ -588,26 +565,29 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
588
565
|
U32 repCode;
|
|
589
566
|
for (repCode = ll0; repCode < lastR; repCode++) {
|
|
590
567
|
U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
|
|
591
|
-
U32 const repIndex =
|
|
568
|
+
U32 const repIndex = curr - repOffset;
|
|
592
569
|
U32 repLen = 0;
|
|
593
|
-
assert(
|
|
594
|
-
if (repOffset-1 /* intentional overflow, discards 0 and -1 */ <
|
|
595
|
-
|
|
570
|
+
assert(curr >= dictLimit);
|
|
571
|
+
if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < curr-dictLimit) { /* equivalent to `curr > repIndex >= dictLimit` */
|
|
572
|
+
/* We must validate the repcode offset because when we're using a dictionary the
|
|
573
|
+
* valid offset range shrinks when the dictionary goes out of bounds.
|
|
574
|
+
*/
|
|
575
|
+
if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) {
|
|
596
576
|
repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;
|
|
597
577
|
}
|
|
598
|
-
} else { /* repIndex < dictLimit || repIndex >=
|
|
578
|
+
} else { /* repIndex < dictLimit || repIndex >= curr */
|
|
599
579
|
const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ?
|
|
600
580
|
dmsBase + repIndex - dmsIndexDelta :
|
|
601
581
|
dictBase + repIndex;
|
|
602
|
-
assert(
|
|
582
|
+
assert(curr >= windowLow);
|
|
603
583
|
if ( dictMode == ZSTD_extDict
|
|
604
|
-
&& ( ((repOffset-1) /*intentional overflow*/ <
|
|
584
|
+
&& ( ((repOffset-1) /*intentional overflow*/ < curr - windowLow) /* equivalent to `curr > repIndex >= windowLow` */
|
|
605
585
|
& (((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */)
|
|
606
586
|
&& (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
|
|
607
587
|
repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch;
|
|
608
588
|
}
|
|
609
589
|
if (dictMode == ZSTD_dictMatchState
|
|
610
|
-
&& ( ((repOffset-1) /*intentional overflow*/ <
|
|
590
|
+
&& ( ((repOffset-1) /*intentional overflow*/ < curr - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `curr > repIndex >= dmsLowLimit` */
|
|
611
591
|
& ((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */
|
|
612
592
|
&& (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
|
|
613
593
|
repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch;
|
|
@@ -627,9 +607,9 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
627
607
|
|
|
628
608
|
/* HC3 match finder */
|
|
629
609
|
if ((mls == 3) /*static*/ && (bestLength < mls)) {
|
|
630
|
-
U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, ip);
|
|
610
|
+
U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip);
|
|
631
611
|
if ((matchIndex3 >= matchLow)
|
|
632
|
-
& (
|
|
612
|
+
& (curr - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
|
|
633
613
|
size_t mlen;
|
|
634
614
|
if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) {
|
|
635
615
|
const BYTE* const match = base + matchIndex3;
|
|
@@ -644,48 +624,48 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
644
624
|
DEBUGLOG(8, "found small match with hlog3, of length %u",
|
|
645
625
|
(U32)mlen);
|
|
646
626
|
bestLength = mlen;
|
|
647
|
-
assert(
|
|
627
|
+
assert(curr > matchIndex3);
|
|
648
628
|
assert(mnum==0); /* no prior solution */
|
|
649
|
-
matches[0].off = (
|
|
629
|
+
matches[0].off = (curr - matchIndex3) + ZSTD_REP_MOVE;
|
|
650
630
|
matches[0].len = (U32)mlen;
|
|
651
631
|
mnum = 1;
|
|
652
632
|
if ( (mlen > sufficient_len) |
|
|
653
633
|
(ip+mlen == iLimit) ) { /* best possible length */
|
|
654
|
-
ms->nextToUpdate =
|
|
634
|
+
ms->nextToUpdate = curr+1; /* skip insertion */
|
|
655
635
|
return 1;
|
|
656
|
-
|
|
657
|
-
}
|
|
658
|
-
}
|
|
636
|
+
} } }
|
|
659
637
|
/* no dictMatchState lookup: dicts don't have a populated HC3 table */
|
|
660
638
|
}
|
|
661
639
|
|
|
662
|
-
hashTable[h] =
|
|
640
|
+
hashTable[h] = curr; /* Update Hash Table */
|
|
663
641
|
|
|
664
642
|
while (nbCompares-- && (matchIndex >= matchLow)) {
|
|
665
643
|
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
|
666
|
-
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
|
667
644
|
const BYTE* match;
|
|
668
|
-
|
|
645
|
+
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
|
646
|
+
assert(curr > matchIndex);
|
|
669
647
|
|
|
670
648
|
if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) {
|
|
671
649
|
assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */
|
|
672
650
|
match = base + matchIndex;
|
|
651
|
+
if (matchIndex >= dictLimit) assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */
|
|
673
652
|
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit);
|
|
674
653
|
} else {
|
|
675
654
|
match = dictBase + matchIndex;
|
|
655
|
+
assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */
|
|
676
656
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
|
|
677
657
|
if (matchIndex+matchLength >= dictLimit)
|
|
678
|
-
match = base + matchIndex; /* prepare for match[matchLength] */
|
|
658
|
+
match = base + matchIndex; /* prepare for match[matchLength] read */
|
|
679
659
|
}
|
|
680
660
|
|
|
681
661
|
if (matchLength > bestLength) {
|
|
682
662
|
DEBUGLOG(8, "found match of length %u at distance %u (offCode=%u)",
|
|
683
|
-
(U32)matchLength,
|
|
663
|
+
(U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE);
|
|
684
664
|
assert(matchEndIdx > matchIndex);
|
|
685
665
|
if (matchLength > matchEndIdx - matchIndex)
|
|
686
666
|
matchEndIdx = matchIndex + (U32)matchLength;
|
|
687
667
|
bestLength = matchLength;
|
|
688
|
-
matches[mnum].off = (
|
|
668
|
+
matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE;
|
|
689
669
|
matches[mnum].len = (U32)matchLength;
|
|
690
670
|
mnum++;
|
|
691
671
|
if ( (matchLength > ZSTD_OPT_NUM)
|
|
@@ -728,11 +708,11 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
728
708
|
if (matchLength > bestLength) {
|
|
729
709
|
matchIndex = dictMatchIndex + dmsIndexDelta;
|
|
730
710
|
DEBUGLOG(8, "found dms match of length %u at distance %u (offCode=%u)",
|
|
731
|
-
(U32)matchLength,
|
|
711
|
+
(U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE);
|
|
732
712
|
if (matchLength > matchEndIdx - matchIndex)
|
|
733
713
|
matchEndIdx = matchIndex + (U32)matchLength;
|
|
734
714
|
bestLength = matchLength;
|
|
735
|
-
matches[mnum].off = (
|
|
715
|
+
matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE;
|
|
736
716
|
matches[mnum].len = (U32)matchLength;
|
|
737
717
|
mnum++;
|
|
738
718
|
if ( (matchLength > ZSTD_OPT_NUM)
|
|
@@ -753,17 +733,20 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
753
733
|
}
|
|
754
734
|
}
|
|
755
735
|
|
|
756
|
-
assert(matchEndIdx >
|
|
736
|
+
assert(matchEndIdx > curr+8);
|
|
757
737
|
ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
|
|
758
738
|
return mnum;
|
|
759
739
|
}
|
|
760
740
|
|
|
761
741
|
|
|
762
742
|
FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
|
|
743
|
+
ZSTD_match_t* matches, /* store result (match found, increasing size) in this table */
|
|
763
744
|
ZSTD_matchState_t* ms,
|
|
745
|
+
U32* nextToUpdate3,
|
|
764
746
|
const BYTE* ip, const BYTE* const iHighLimit, const ZSTD_dictMode_e dictMode,
|
|
765
|
-
U32 rep[ZSTD_REP_NUM],
|
|
766
|
-
|
|
747
|
+
const U32 rep[ZSTD_REP_NUM],
|
|
748
|
+
U32 const ll0,
|
|
749
|
+
U32 const lengthToBeat)
|
|
767
750
|
{
|
|
768
751
|
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
|
769
752
|
U32 const matchLengthSearch = cParams->minMatch;
|
|
@@ -772,44 +755,154 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
|
|
|
772
755
|
ZSTD_updateTree_internal(ms, ip, iHighLimit, matchLengthSearch, dictMode);
|
|
773
756
|
switch(matchLengthSearch)
|
|
774
757
|
{
|
|
775
|
-
case 3 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0,
|
|
758
|
+
case 3 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 3);
|
|
776
759
|
default :
|
|
777
|
-
case 4 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0,
|
|
778
|
-
case 5 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0,
|
|
760
|
+
case 4 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 4);
|
|
761
|
+
case 5 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 5);
|
|
779
762
|
case 7 :
|
|
780
|
-
case 6 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0,
|
|
763
|
+
case 6 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 6);
|
|
781
764
|
}
|
|
782
765
|
}
|
|
783
766
|
|
|
767
|
+
/*************************
|
|
768
|
+
* LDM helper functions *
|
|
769
|
+
*************************/
|
|
784
770
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
U32
|
|
790
|
-
|
|
771
|
+
/* Struct containing info needed to make decision about ldm inclusion */
|
|
772
|
+
typedef struct {
|
|
773
|
+
rawSeqStore_t seqStore; /* External match candidates store for this block */
|
|
774
|
+
U32 startPosInBlock; /* Start position of the current match candidate */
|
|
775
|
+
U32 endPosInBlock; /* End position of the current match candidate */
|
|
776
|
+
U32 offset; /* Offset of the match candidate */
|
|
777
|
+
} ZSTD_optLdm_t;
|
|
791
778
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
newReps.rep[0] = currentOffset;
|
|
806
|
-
} else { /* repCode == 0 */
|
|
807
|
-
memcpy(&newReps, rep, sizeof(newReps));
|
|
779
|
+
/* ZSTD_optLdm_skipRawSeqStoreBytes():
|
|
780
|
+
* Moves forward in rawSeqStore by nbBytes, which will update the fields 'pos' and 'posInSequence'.
|
|
781
|
+
*/
|
|
782
|
+
static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
|
|
783
|
+
U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes);
|
|
784
|
+
while (currPos && rawSeqStore->pos < rawSeqStore->size) {
|
|
785
|
+
rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
|
|
786
|
+
if (currPos >= currSeq.litLength + currSeq.matchLength) {
|
|
787
|
+
currPos -= currSeq.litLength + currSeq.matchLength;
|
|
788
|
+
rawSeqStore->pos++;
|
|
789
|
+
} else {
|
|
790
|
+
rawSeqStore->posInSequence = currPos;
|
|
791
|
+
break;
|
|
808
792
|
}
|
|
809
793
|
}
|
|
810
|
-
|
|
794
|
+
if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) {
|
|
795
|
+
rawSeqStore->posInSequence = 0;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/* ZSTD_opt_getNextMatchAndUpdateSeqStore():
|
|
800
|
+
* Calculates the beginning and end of the next match in the current block.
|
|
801
|
+
* Updates 'pos' and 'posInSequence' of the ldmSeqStore.
|
|
802
|
+
*/
|
|
803
|
+
static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock,
|
|
804
|
+
U32 blockBytesRemaining) {
|
|
805
|
+
rawSeq currSeq;
|
|
806
|
+
U32 currBlockEndPos;
|
|
807
|
+
U32 literalsBytesRemaining;
|
|
808
|
+
U32 matchBytesRemaining;
|
|
809
|
+
|
|
810
|
+
/* Setting match end position to MAX to ensure we never use an LDM during this block */
|
|
811
|
+
if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
|
|
812
|
+
optLdm->startPosInBlock = UINT_MAX;
|
|
813
|
+
optLdm->endPosInBlock = UINT_MAX;
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
/* Calculate appropriate bytes left in matchLength and litLength after adjusting
|
|
817
|
+
based on ldmSeqStore->posInSequence */
|
|
818
|
+
currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos];
|
|
819
|
+
assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength);
|
|
820
|
+
currBlockEndPos = currPosInBlock + blockBytesRemaining;
|
|
821
|
+
literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ?
|
|
822
|
+
currSeq.litLength - (U32)optLdm->seqStore.posInSequence :
|
|
823
|
+
0;
|
|
824
|
+
matchBytesRemaining = (literalsBytesRemaining == 0) ?
|
|
825
|
+
currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) :
|
|
826
|
+
currSeq.matchLength;
|
|
827
|
+
|
|
828
|
+
/* If there are more literal bytes than bytes remaining in block, no ldm is possible */
|
|
829
|
+
if (literalsBytesRemaining >= blockBytesRemaining) {
|
|
830
|
+
optLdm->startPosInBlock = UINT_MAX;
|
|
831
|
+
optLdm->endPosInBlock = UINT_MAX;
|
|
832
|
+
ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining);
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/* Matches may be < MINMATCH by this process. In that case, we will reject them
|
|
837
|
+
when we are deciding whether or not to add the ldm */
|
|
838
|
+
optLdm->startPosInBlock = currPosInBlock + literalsBytesRemaining;
|
|
839
|
+
optLdm->endPosInBlock = optLdm->startPosInBlock + matchBytesRemaining;
|
|
840
|
+
optLdm->offset = currSeq.offset;
|
|
841
|
+
|
|
842
|
+
if (optLdm->endPosInBlock > currBlockEndPos) {
|
|
843
|
+
/* Match ends after the block ends, we can't use the whole match */
|
|
844
|
+
optLdm->endPosInBlock = currBlockEndPos;
|
|
845
|
+
ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock);
|
|
846
|
+
} else {
|
|
847
|
+
/* Consume nb of bytes equal to size of sequence left */
|
|
848
|
+
ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/* ZSTD_optLdm_maybeAddMatch():
|
|
853
|
+
* Adds a match if it's long enough, based on it's 'matchStartPosInBlock'
|
|
854
|
+
* and 'matchEndPosInBlock', into 'matches'. Maintains the correct ordering of 'matches'
|
|
855
|
+
*/
|
|
856
|
+
static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
|
|
857
|
+
ZSTD_optLdm_t* optLdm, U32 currPosInBlock) {
|
|
858
|
+
U32 posDiff = currPosInBlock - optLdm->startPosInBlock;
|
|
859
|
+
/* Note: ZSTD_match_t actually contains offCode and matchLength (before subtracting MINMATCH) */
|
|
860
|
+
U32 candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff;
|
|
861
|
+
U32 candidateOffCode = optLdm->offset + ZSTD_REP_MOVE;
|
|
862
|
+
|
|
863
|
+
/* Ensure that current block position is not outside of the match */
|
|
864
|
+
if (currPosInBlock < optLdm->startPosInBlock
|
|
865
|
+
|| currPosInBlock >= optLdm->endPosInBlock
|
|
866
|
+
|| candidateMatchLength < MINMATCH) {
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) {
|
|
871
|
+
DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offCode: %u matchLength %u) at block position=%u",
|
|
872
|
+
candidateOffCode, candidateMatchLength, currPosInBlock);
|
|
873
|
+
matches[*nbMatches].len = candidateMatchLength;
|
|
874
|
+
matches[*nbMatches].off = candidateOffCode;
|
|
875
|
+
(*nbMatches)++;
|
|
876
|
+
}
|
|
811
877
|
}
|
|
812
878
|
|
|
879
|
+
/* ZSTD_optLdm_processMatchCandidate():
|
|
880
|
+
* Wrapper function to update ldm seq store and call ldm functions as necessary.
|
|
881
|
+
*/
|
|
882
|
+
static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_t* matches, U32* nbMatches,
|
|
883
|
+
U32 currPosInBlock, U32 remainingBytes) {
|
|
884
|
+
if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
if (currPosInBlock >= optLdm->endPosInBlock) {
|
|
889
|
+
if (currPosInBlock > optLdm->endPosInBlock) {
|
|
890
|
+
/* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily
|
|
891
|
+
* at the end of a match from the ldm seq store, and will often be some bytes
|
|
892
|
+
* over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots"
|
|
893
|
+
*/
|
|
894
|
+
U32 posOvershoot = currPosInBlock - optLdm->endPosInBlock;
|
|
895
|
+
ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot);
|
|
896
|
+
}
|
|
897
|
+
ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes);
|
|
898
|
+
}
|
|
899
|
+
ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
/*-*******************************
|
|
903
|
+
* Optimal parser
|
|
904
|
+
*********************************/
|
|
905
|
+
|
|
813
906
|
|
|
814
907
|
static U32 ZSTD_totalLen(ZSTD_optimal_t sol)
|
|
815
908
|
{
|
|
@@ -825,7 +918,7 @@ listStats(const U32* table, int lastEltID)
|
|
|
825
918
|
int enb;
|
|
826
919
|
for (enb=0; enb < nbElts; enb++) {
|
|
827
920
|
(void)table;
|
|
828
|
-
|
|
921
|
+
/* RAWLOG(2, "%3i:%3i, ", enb, table[enb]); */
|
|
829
922
|
RAWLOG(2, "%4i,", table[enb]);
|
|
830
923
|
}
|
|
831
924
|
RAWLOG(2, " \n");
|
|
@@ -853,16 +946,21 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
853
946
|
|
|
854
947
|
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
|
|
855
948
|
U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4;
|
|
949
|
+
U32 nextToUpdate3 = ms->nextToUpdate;
|
|
856
950
|
|
|
857
951
|
ZSTD_optimal_t* const opt = optStatePtr->priceTable;
|
|
858
952
|
ZSTD_match_t* const matches = optStatePtr->matchTable;
|
|
859
953
|
ZSTD_optimal_t lastSequence;
|
|
954
|
+
ZSTD_optLdm_t optLdm;
|
|
955
|
+
|
|
956
|
+
optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore;
|
|
957
|
+
optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0;
|
|
958
|
+
ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip));
|
|
860
959
|
|
|
861
960
|
/* init */
|
|
862
961
|
DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u",
|
|
863
962
|
(U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate);
|
|
864
963
|
assert(optLevel <= 2);
|
|
865
|
-
ms->nextToUpdate3 = ms->nextToUpdate;
|
|
866
964
|
ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel);
|
|
867
965
|
ip += (ip==prefixStart);
|
|
868
966
|
|
|
@@ -873,14 +971,21 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
873
971
|
/* find first match */
|
|
874
972
|
{ U32 const litlen = (U32)(ip - anchor);
|
|
875
973
|
U32 const ll0 = !litlen;
|
|
876
|
-
U32
|
|
974
|
+
U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);
|
|
975
|
+
ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
|
|
976
|
+
(U32)(ip-istart), (U32)(iend - ip));
|
|
877
977
|
if (!nbMatches) { ip++; continue; }
|
|
878
978
|
|
|
879
979
|
/* initialize opt[0] */
|
|
880
980
|
{ U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
|
|
881
981
|
opt[0].mlen = 0; /* means is_a_literal */
|
|
882
982
|
opt[0].litlen = litlen;
|
|
883
|
-
|
|
983
|
+
/* We don't need to include the actual price of the literals because
|
|
984
|
+
* it is static for the duration of the forward pass, and is included
|
|
985
|
+
* in every price. We include the literal length to avoid negative
|
|
986
|
+
* prices when we subtract the previous literal length.
|
|
987
|
+
*/
|
|
988
|
+
opt[0].price = ZSTD_litLengthPrice(litlen, optStatePtr, optLevel);
|
|
884
989
|
|
|
885
990
|
/* large match -> immediate encoding */
|
|
886
991
|
{ U32 const maxML = matches[nbMatches-1].len;
|
|
@@ -909,7 +1014,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
909
1014
|
for (matchNb = 0; matchNb < nbMatches; matchNb++) {
|
|
910
1015
|
U32 const offset = matches[matchNb].off;
|
|
911
1016
|
U32 const end = matches[matchNb].len;
|
|
912
|
-
repcodes_t const repHistory = ZSTD_updateRep(rep, offset, ll0);
|
|
913
1017
|
for ( ; pos <= end ; pos++ ) {
|
|
914
1018
|
U32 const matchPrice = ZSTD_getMatchPrice(offset, pos, optStatePtr, optLevel);
|
|
915
1019
|
U32 const sequencePrice = literalsPrice + matchPrice;
|
|
@@ -919,8 +1023,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
919
1023
|
opt[pos].off = offset;
|
|
920
1024
|
opt[pos].litlen = litlen;
|
|
921
1025
|
opt[pos].price = sequencePrice;
|
|
922
|
-
ZSTD_STATIC_ASSERT(sizeof(opt[pos].rep) == sizeof(repHistory));
|
|
923
|
-
memcpy(opt[pos].rep, &repHistory, sizeof(repHistory));
|
|
924
1026
|
} }
|
|
925
1027
|
last_pos = pos-1;
|
|
926
1028
|
}
|
|
@@ -947,7 +1049,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
947
1049
|
opt[cur].off = 0;
|
|
948
1050
|
opt[cur].litlen = litlen;
|
|
949
1051
|
opt[cur].price = price;
|
|
950
|
-
memcpy(opt[cur].rep, opt[cur-1].rep, sizeof(opt[cur].rep));
|
|
951
1052
|
} else {
|
|
952
1053
|
DEBUGLOG(7, "cPos:%zi==rPos:%u : literal would cost more (%.2f>%.2f) (hist:%u,%u,%u)",
|
|
953
1054
|
inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price),
|
|
@@ -955,6 +1056,21 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
955
1056
|
}
|
|
956
1057
|
}
|
|
957
1058
|
|
|
1059
|
+
/* Set the repcodes of the current position. We must do it here
|
|
1060
|
+
* because we rely on the repcodes of the 2nd to last sequence being
|
|
1061
|
+
* correct to set the next chunks repcodes during the backward
|
|
1062
|
+
* traversal.
|
|
1063
|
+
*/
|
|
1064
|
+
ZSTD_STATIC_ASSERT(sizeof(opt[cur].rep) == sizeof(repcodes_t));
|
|
1065
|
+
assert(cur >= opt[cur].mlen);
|
|
1066
|
+
if (opt[cur].mlen != 0) {
|
|
1067
|
+
U32 const prev = cur - opt[cur].mlen;
|
|
1068
|
+
repcodes_t newReps = ZSTD_updateRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0);
|
|
1069
|
+
ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t));
|
|
1070
|
+
} else {
|
|
1071
|
+
ZSTD_memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t));
|
|
1072
|
+
}
|
|
1073
|
+
|
|
958
1074
|
/* last match must start at a minimum distance of 8 from oend */
|
|
959
1075
|
if (inr > ilimit) continue;
|
|
960
1076
|
|
|
@@ -970,8 +1086,12 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
970
1086
|
U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
|
|
971
1087
|
U32 const previousPrice = opt[cur].price;
|
|
972
1088
|
U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
|
|
973
|
-
U32
|
|
1089
|
+
U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);
|
|
974
1090
|
U32 matchNb;
|
|
1091
|
+
|
|
1092
|
+
ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
|
|
1093
|
+
(U32)(inr-istart), (U32)(iend-inr));
|
|
1094
|
+
|
|
975
1095
|
if (!nbMatches) {
|
|
976
1096
|
DEBUGLOG(7, "rPos:%u : no match found", cur);
|
|
977
1097
|
continue;
|
|
@@ -995,7 +1115,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
995
1115
|
/* set prices using matches found at position == cur */
|
|
996
1116
|
for (matchNb = 0; matchNb < nbMatches; matchNb++) {
|
|
997
1117
|
U32 const offset = matches[matchNb].off;
|
|
998
|
-
repcodes_t const repHistory = ZSTD_updateRep(opt[cur].rep, offset, ll0);
|
|
999
1118
|
U32 const lastML = matches[matchNb].len;
|
|
1000
1119
|
U32 const startML = (matchNb>0) ? matches[matchNb-1].len+1 : minMatch;
|
|
1001
1120
|
U32 mlen;
|
|
@@ -1015,8 +1134,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
1015
1134
|
opt[pos].off = offset;
|
|
1016
1135
|
opt[pos].litlen = litlen;
|
|
1017
1136
|
opt[pos].price = price;
|
|
1018
|
-
ZSTD_STATIC_ASSERT(sizeof(opt[pos].rep) == sizeof(repHistory));
|
|
1019
|
-
memcpy(opt[pos].rep, &repHistory, sizeof(repHistory));
|
|
1020
1137
|
} else {
|
|
1021
1138
|
DEBUGLOG(7, "rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)",
|
|
1022
1139
|
pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price));
|
|
@@ -1032,6 +1149,17 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
1032
1149
|
_shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
|
|
1033
1150
|
assert(opt[0].mlen == 0);
|
|
1034
1151
|
|
|
1152
|
+
/* Set the next chunk's repcodes based on the repcodes of the beginning
|
|
1153
|
+
* of the last match, and the last sequence. This avoids us having to
|
|
1154
|
+
* update them while traversing the sequences.
|
|
1155
|
+
*/
|
|
1156
|
+
if (lastSequence.mlen != 0) {
|
|
1157
|
+
repcodes_t reps = ZSTD_updateRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0);
|
|
1158
|
+
ZSTD_memcpy(rep, &reps, sizeof(reps));
|
|
1159
|
+
} else {
|
|
1160
|
+
ZSTD_memcpy(rep, opt[cur].rep, sizeof(repcodes_t));
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1035
1163
|
{ U32 const storeEnd = cur + 1;
|
|
1036
1164
|
U32 storeStart = storeEnd;
|
|
1037
1165
|
U32 seqPos = cur;
|
|
@@ -1068,33 +1196,18 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
|
|
|
1068
1196
|
continue; /* will finish */
|
|
1069
1197
|
}
|
|
1070
1198
|
|
|
1071
|
-
/* repcodes update : like ZSTD_updateRep(), but update in place */
|
|
1072
|
-
if (offCode >= ZSTD_REP_NUM) { /* full offset */
|
|
1073
|
-
rep[2] = rep[1];
|
|
1074
|
-
rep[1] = rep[0];
|
|
1075
|
-
rep[0] = offCode - ZSTD_REP_MOVE;
|
|
1076
|
-
} else { /* repcode */
|
|
1077
|
-
U32 const repCode = offCode + (llen==0);
|
|
1078
|
-
if (repCode) { /* note : if repCode==0, no change */
|
|
1079
|
-
U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
|
|
1080
|
-
if (repCode >= 2) rep[2] = rep[1];
|
|
1081
|
-
rep[1] = rep[0];
|
|
1082
|
-
rep[0] = currentOffset;
|
|
1083
|
-
} }
|
|
1084
|
-
|
|
1085
1199
|
assert(anchor + llen <= iend);
|
|
1086
1200
|
ZSTD_updateStats(optStatePtr, llen, anchor, offCode, mlen);
|
|
1087
|
-
ZSTD_storeSeq(seqStore, llen, anchor, offCode, mlen-MINMATCH);
|
|
1201
|
+
ZSTD_storeSeq(seqStore, llen, anchor, iend, offCode, mlen-MINMATCH);
|
|
1088
1202
|
anchor += advance;
|
|
1089
1203
|
ip = anchor;
|
|
1090
1204
|
} }
|
|
1091
1205
|
ZSTD_setBasePrices(optStatePtr, optLevel);
|
|
1092
1206
|
}
|
|
1093
|
-
|
|
1094
1207
|
} /* while (ip < ilimit) */
|
|
1095
1208
|
|
|
1096
1209
|
/* Return the last literals size */
|
|
1097
|
-
return iend - anchor;
|
|
1210
|
+
return (size_t)(iend - anchor);
|
|
1098
1211
|
}
|
|
1099
1212
|
|
|
1100
1213
|
|
|
@@ -1142,7 +1255,7 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
|
|
|
1142
1255
|
const void* src, size_t srcSize)
|
|
1143
1256
|
{
|
|
1144
1257
|
U32 tmpRep[ZSTD_REP_NUM]; /* updated rep codes will sink here */
|
|
1145
|
-
|
|
1258
|
+
ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep));
|
|
1146
1259
|
|
|
1147
1260
|
DEBUGLOG(4, "ZSTD_initStats_ultra (srcSize=%zu)", srcSize);
|
|
1148
1261
|
assert(ms->opt.litLengthSum == 0); /* first block */
|
|
@@ -1158,7 +1271,6 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
|
|
|
1158
1271
|
ms->window.dictLimit += (U32)srcSize;
|
|
1159
1272
|
ms->window.lowLimit = ms->window.dictLimit;
|
|
1160
1273
|
ms->nextToUpdate = ms->window.dictLimit;
|
|
1161
|
-
ms->nextToUpdate3 = ms->window.dictLimit;
|
|
1162
1274
|
|
|
1163
1275
|
/* re-inforce weight of collected statistics */
|
|
1164
1276
|
ZSTD_upscaleStats(&ms->opt);
|
|
@@ -1176,7 +1288,7 @@ size_t ZSTD_compressBlock_btultra2(
|
|
|
1176
1288
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
1177
1289
|
const void* src, size_t srcSize)
|
|
1178
1290
|
{
|
|
1179
|
-
U32 const
|
|
1291
|
+
U32 const curr = (U32)((const BYTE*)src - ms->window.base);
|
|
1180
1292
|
DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize);
|
|
1181
1293
|
|
|
1182
1294
|
/* 2-pass strategy:
|
|
@@ -1191,7 +1303,7 @@ size_t ZSTD_compressBlock_btultra2(
|
|
|
1191
1303
|
if ( (ms->opt.litLengthSum==0) /* first block */
|
|
1192
1304
|
&& (seqStore->sequences == seqStore->sequencesStart) /* no ldm */
|
|
1193
1305
|
&& (ms->window.dictLimit == ms->window.lowLimit) /* no dictionary */
|
|
1194
|
-
&& (
|
|
1306
|
+
&& (curr == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */
|
|
1195
1307
|
&& (srcSize > ZSTD_PREDEF_THRESHOLD)
|
|
1196
1308
|
) {
|
|
1197
1309
|
ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize);
|