extzstd 0.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.ja.md +39 -0
  3. data/README.md +38 -56
  4. data/contrib/zstd/CHANGELOG +613 -0
  5. data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
  6. data/contrib/zstd/CONTRIBUTING.md +406 -0
  7. data/contrib/zstd/COPYING +339 -0
  8. data/contrib/zstd/Makefile +420 -0
  9. data/contrib/zstd/README.md +179 -41
  10. data/contrib/zstd/TESTING.md +44 -0
  11. data/contrib/zstd/appveyor.yml +292 -0
  12. data/contrib/zstd/lib/BUCK +234 -0
  13. data/contrib/zstd/lib/Makefile +451 -0
  14. data/contrib/zstd/lib/README.md +207 -0
  15. data/contrib/zstd/{common → lib/common}/bitstream.h +187 -138
  16. data/contrib/zstd/lib/common/compiler.h +288 -0
  17. data/contrib/zstd/lib/common/cpu.h +213 -0
  18. data/contrib/zstd/lib/common/debug.c +24 -0
  19. data/contrib/zstd/lib/common/debug.h +107 -0
  20. data/contrib/zstd/lib/common/entropy_common.c +362 -0
  21. data/contrib/zstd/{common → lib/common}/error_private.c +25 -12
  22. data/contrib/zstd/{common → lib/common}/error_private.h +14 -10
  23. data/contrib/zstd/{common → lib/common}/fse.h +173 -92
  24. data/contrib/zstd/{common → lib/common}/fse_decompress.c +149 -85
  25. data/contrib/zstd/lib/common/huf.h +361 -0
  26. data/contrib/zstd/{common → lib/common}/mem.h +115 -59
  27. data/contrib/zstd/lib/common/pool.c +350 -0
  28. data/contrib/zstd/lib/common/pool.h +84 -0
  29. data/contrib/zstd/lib/common/threading.c +122 -0
  30. data/contrib/zstd/lib/common/threading.h +155 -0
  31. data/contrib/zstd/{common → lib/common}/xxhash.c +55 -96
  32. data/contrib/zstd/{common → lib/common}/xxhash.h +23 -47
  33. data/contrib/zstd/lib/common/zstd_common.c +83 -0
  34. data/contrib/zstd/lib/common/zstd_deps.h +111 -0
  35. data/contrib/zstd/lib/common/zstd_errors.h +95 -0
  36. data/contrib/zstd/lib/common/zstd_internal.h +478 -0
  37. data/contrib/zstd/{compress → lib/compress}/fse_compress.c +214 -319
  38. data/contrib/zstd/lib/compress/hist.c +181 -0
  39. data/contrib/zstd/lib/compress/hist.h +75 -0
  40. data/contrib/zstd/lib/compress/huf_compress.c +913 -0
  41. data/contrib/zstd/lib/compress/zstd_compress.c +5208 -0
  42. data/contrib/zstd/lib/compress/zstd_compress_internal.h +1203 -0
  43. data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
  44. data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
  45. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +433 -0
  46. data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
  47. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +849 -0
  48. data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
  49. data/contrib/zstd/lib/compress/zstd_cwksp.h +561 -0
  50. data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
  51. data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
  52. data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
  53. data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
  54. data/contrib/zstd/lib/compress/zstd_lazy.c +1412 -0
  55. data/contrib/zstd/lib/compress/zstd_lazy.h +87 -0
  56. data/contrib/zstd/lib/compress/zstd_ldm.c +660 -0
  57. data/contrib/zstd/lib/compress/zstd_ldm.h +116 -0
  58. data/contrib/zstd/lib/compress/zstd_opt.c +1345 -0
  59. data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
  60. data/contrib/zstd/lib/compress/zstdmt_compress.c +1811 -0
  61. data/contrib/zstd/lib/compress/zstdmt_compress.h +110 -0
  62. data/contrib/zstd/lib/decompress/huf_decompress.c +1350 -0
  63. data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
  64. data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
  65. data/contrib/zstd/lib/decompress/zstd_decompress.c +1930 -0
  66. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1540 -0
  67. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +62 -0
  68. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +190 -0
  69. data/contrib/zstd/{common → lib/deprecated}/zbuff.h +68 -45
  70. data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
  71. data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
  72. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
  73. data/contrib/zstd/lib/dictBuilder/cover.c +1245 -0
  74. data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
  75. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
  76. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +0 -0
  77. data/contrib/zstd/lib/dictBuilder/fastcover.c +758 -0
  78. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +318 -194
  79. data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
  80. data/contrib/zstd/{legacy → lib/legacy}/zstd_legacy.h +171 -15
  81. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +191 -124
  82. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +19 -5
  83. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +125 -125
  84. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +19 -5
  85. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +125 -124
  86. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +20 -6
  87. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +151 -299
  88. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +19 -5
  89. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +237 -243
  90. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +19 -6
  91. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +130 -143
  92. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +18 -5
  93. data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.c +158 -157
  94. data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.h +19 -5
  95. data/contrib/zstd/lib/libzstd.pc.in +15 -0
  96. data/contrib/zstd/lib/zstd.h +2391 -0
  97. data/ext/depend +2 -0
  98. data/ext/extconf.rb +15 -6
  99. data/ext/extzstd.c +76 -145
  100. data/ext/extzstd.h +80 -31
  101. data/ext/extzstd_stream.c +417 -142
  102. data/ext/libzstd_conf.h +8 -0
  103. data/ext/zstd_common.c +10 -7
  104. data/ext/zstd_compress.c +14 -5
  105. data/ext/zstd_decompress.c +5 -4
  106. data/ext/zstd_dictbuilder.c +9 -4
  107. data/ext/zstd_dictbuilder_fastcover.c +3 -0
  108. data/ext/zstd_legacy_v01.c +3 -1
  109. data/ext/zstd_legacy_v02.c +3 -1
  110. data/ext/zstd_legacy_v03.c +3 -1
  111. data/ext/zstd_legacy_v04.c +3 -1
  112. data/ext/zstd_legacy_v05.c +3 -1
  113. data/ext/zstd_legacy_v06.c +3 -1
  114. data/ext/zstd_legacy_v07.c +3 -1
  115. data/gemstub.rb +10 -24
  116. data/lib/extzstd.rb +64 -179
  117. data/lib/extzstd/version.rb +6 -1
  118. data/test/test_basic.rb +9 -6
  119. metadata +113 -57
  120. data/HISTORY.ja +0 -5
  121. data/contrib/zstd/common/entropy_common.c +0 -225
  122. data/contrib/zstd/common/huf.h +0 -228
  123. data/contrib/zstd/common/zstd_common.c +0 -83
  124. data/contrib/zstd/common/zstd_errors.h +0 -60
  125. data/contrib/zstd/common/zstd_internal.h +0 -267
  126. data/contrib/zstd/compress/huf_compress.c +0 -533
  127. data/contrib/zstd/compress/zbuff_compress.c +0 -319
  128. data/contrib/zstd/compress/zstd_compress.c +0 -3264
  129. data/contrib/zstd/compress/zstd_opt.h +0 -900
  130. data/contrib/zstd/decompress/huf_decompress.c +0 -883
  131. data/contrib/zstd/decompress/zbuff_decompress.c +0 -252
  132. data/contrib/zstd/decompress/zstd_decompress.c +0 -1842
  133. data/contrib/zstd/dictBuilder/zdict.h +0 -111
  134. data/contrib/zstd/zstd.h +0 -640
@@ -0,0 +1,158 @@
1
+ /*
2
+ * Copyright (c) 2016-2020, 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
+ /*-*************************************
12
+ * Dependencies
13
+ ***************************************/
14
+ #include "zstd_compress_literals.h"
15
+
16
+ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
17
+ {
18
+ BYTE* const ostart = (BYTE* const)dst;
19
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
20
+
21
+ RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall, "");
22
+
23
+ switch(flSize)
24
+ {
25
+ case 1: /* 2 - 1 - 5 */
26
+ ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
27
+ break;
28
+ case 2: /* 2 - 2 - 12 */
29
+ MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
30
+ break;
31
+ case 3: /* 2 - 2 - 20 */
32
+ MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
33
+ break;
34
+ default: /* not necessary : flSize is {1,2,3} */
35
+ assert(0);
36
+ }
37
+
38
+ ZSTD_memcpy(ostart + flSize, src, srcSize);
39
+ DEBUGLOG(5, "Raw literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize));
40
+ return srcSize + flSize;
41
+ }
42
+
43
+ size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
44
+ {
45
+ BYTE* const ostart = (BYTE* const)dst;
46
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
47
+
48
+ (void)dstCapacity; /* dstCapacity already guaranteed to be >=4, hence large enough */
49
+
50
+ switch(flSize)
51
+ {
52
+ case 1: /* 2 - 1 - 5 */
53
+ ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
54
+ break;
55
+ case 2: /* 2 - 2 - 12 */
56
+ MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
57
+ break;
58
+ case 3: /* 2 - 2 - 20 */
59
+ MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
60
+ break;
61
+ default: /* not necessary : flSize is {1,2,3} */
62
+ assert(0);
63
+ }
64
+
65
+ ostart[flSize] = *(const BYTE*)src;
66
+ DEBUGLOG(5, "RLE literals: %u -> %u", (U32)srcSize, (U32)flSize + 1);
67
+ return flSize+1;
68
+ }
69
+
70
+ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
71
+ ZSTD_hufCTables_t* nextHuf,
72
+ ZSTD_strategy strategy, int disableLiteralCompression,
73
+ void* dst, size_t dstCapacity,
74
+ const void* src, size_t srcSize,
75
+ void* entropyWorkspace, size_t entropyWorkspaceSize,
76
+ const int bmi2)
77
+ {
78
+ size_t const minGain = ZSTD_minGain(srcSize, strategy);
79
+ size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
80
+ BYTE* const ostart = (BYTE*)dst;
81
+ U32 singleStream = srcSize < 256;
82
+ symbolEncodingType_e hType = set_compressed;
83
+ size_t cLitSize;
84
+
85
+ DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i srcSize=%u)",
86
+ disableLiteralCompression, (U32)srcSize);
87
+
88
+ /* Prepare nextEntropy assuming reusing the existing table */
89
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
90
+
91
+ if (disableLiteralCompression)
92
+ return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
93
+
94
+ /* small ? don't even attempt compression (speed opt) */
95
+ # define COMPRESS_LITERALS_SIZE_MIN 63
96
+ { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
97
+ if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
98
+ }
99
+
100
+ RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression");
101
+ { HUF_repeat repeat = prevHuf->repeatMode;
102
+ int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
103
+ if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
104
+ cLitSize = singleStream ?
105
+ HUF_compress1X_repeat(
106
+ ostart+lhSize, dstCapacity-lhSize, src, srcSize,
107
+ HUF_SYMBOLVALUE_MAX, HUF_TABLELOG_DEFAULT, entropyWorkspace, entropyWorkspaceSize,
108
+ (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2) :
109
+ HUF_compress4X_repeat(
110
+ ostart+lhSize, dstCapacity-lhSize, src, srcSize,
111
+ HUF_SYMBOLVALUE_MAX, HUF_TABLELOG_DEFAULT, entropyWorkspace, entropyWorkspaceSize,
112
+ (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
113
+ if (repeat != HUF_repeat_none) {
114
+ /* reused the existing table */
115
+ DEBUGLOG(5, "Reusing previous huffman table");
116
+ hType = set_repeat;
117
+ }
118
+ }
119
+
120
+ if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
121
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
122
+ return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
123
+ }
124
+ if (cLitSize==1) {
125
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
126
+ return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
127
+ }
128
+
129
+ if (hType == set_compressed) {
130
+ /* using a newly constructed table */
131
+ nextHuf->repeatMode = HUF_repeat_check;
132
+ }
133
+
134
+ /* Build header */
135
+ switch(lhSize)
136
+ {
137
+ case 3: /* 2 - 2 - 10 - 10 */
138
+ { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
139
+ MEM_writeLE24(ostart, lhc);
140
+ break;
141
+ }
142
+ case 4: /* 2 - 2 - 14 - 14 */
143
+ { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
144
+ MEM_writeLE32(ostart, lhc);
145
+ break;
146
+ }
147
+ case 5: /* 2 - 2 - 18 - 18 */
148
+ { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
149
+ MEM_writeLE32(ostart, lhc);
150
+ ostart[4] = (BYTE)(cLitSize >> 10);
151
+ break;
152
+ }
153
+ default: /* not possible : lhSize is {3,4,5} */
154
+ assert(0);
155
+ }
156
+ DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)srcSize, (U32)(lhSize+cLitSize));
157
+ return lhSize+cLitSize;
158
+ }
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Copyright (c) 2016-2020, 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_COMPRESS_LITERALS_H
12
+ #define ZSTD_COMPRESS_LITERALS_H
13
+
14
+ #include "zstd_compress_internal.h" /* ZSTD_hufCTables_t, ZSTD_minGain() */
15
+
16
+
17
+ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
18
+
19
+ size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
20
+
21
+ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
22
+ ZSTD_hufCTables_t* nextHuf,
23
+ ZSTD_strategy strategy, int disableLiteralCompression,
24
+ void* dst, size_t dstCapacity,
25
+ const void* src, size_t srcSize,
26
+ void* entropyWorkspace, size_t entropyWorkspaceSize,
27
+ const int bmi2);
28
+
29
+ #endif /* ZSTD_COMPRESS_LITERALS_H */
@@ -0,0 +1,433 @@
1
+ /*
2
+ * Copyright (c) 2016-2020, 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
+ /*-*************************************
12
+ * Dependencies
13
+ ***************************************/
14
+ #include "zstd_compress_sequences.h"
15
+
16
+ /**
17
+ * -log2(x / 256) lookup table for x in [0, 256).
18
+ * If x == 0: Return 0
19
+ * Else: Return floor(-log2(x / 256) * 256)
20
+ */
21
+ static unsigned const kInverseProbabilityLog256[256] = {
22
+ 0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,
23
+ 1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889,
24
+ 874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734,
25
+ 724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626,
26
+ 618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542,
27
+ 535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473,
28
+ 468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415,
29
+ 411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366,
30
+ 362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322,
31
+ 318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282,
32
+ 279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247,
33
+ 244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215,
34
+ 212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185,
35
+ 182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157,
36
+ 155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132,
37
+ 130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108,
38
+ 106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85,
39
+ 83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64,
40
+ 62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44,
41
+ 42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25,
42
+ 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7,
43
+ 5, 4, 2, 1,
44
+ };
45
+
46
+ static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
47
+ void const* ptr = ctable;
48
+ U16 const* u16ptr = (U16 const*)ptr;
49
+ U32 const maxSymbolValue = MEM_read16(u16ptr + 1);
50
+ return maxSymbolValue;
51
+ }
52
+
53
+ /**
54
+ * Returns true if we should use ncount=-1 else we should
55
+ * use ncount=1 for low probability symbols instead.
56
+ */
57
+ static unsigned ZSTD_useLowProbCount(size_t const nbSeq)
58
+ {
59
+ /* Heuristic: This should cover most blocks <= 16K and
60
+ * start to fade out after 16K to about 32K depending on
61
+ * comprssibility.
62
+ */
63
+ return nbSeq >= 2048;
64
+ }
65
+
66
+ /**
67
+ * Returns the cost in bytes of encoding the normalized count header.
68
+ * Returns an error if any of the helper functions return an error.
69
+ */
70
+ static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
71
+ size_t const nbSeq, unsigned const FSELog)
72
+ {
73
+ BYTE wksp[FSE_NCOUNTBOUND];
74
+ S16 norm[MaxSeq + 1];
75
+ const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
76
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), "");
77
+ return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
78
+ }
79
+
80
+ /**
81
+ * Returns the cost in bits of encoding the distribution described by count
82
+ * using the entropy bound.
83
+ */
84
+ static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)
85
+ {
86
+ unsigned cost = 0;
87
+ unsigned s;
88
+ for (s = 0; s <= max; ++s) {
89
+ unsigned norm = (unsigned)((256 * count[s]) / total);
90
+ if (count[s] != 0 && norm == 0)
91
+ norm = 1;
92
+ assert(count[s] < total);
93
+ cost += count[s] * kInverseProbabilityLog256[norm];
94
+ }
95
+ return cost >> 8;
96
+ }
97
+
98
+ /**
99
+ * Returns the cost in bits of encoding the distribution in count using ctable.
100
+ * Returns an error if ctable cannot represent all the symbols in count.
101
+ */
102
+ size_t ZSTD_fseBitCost(
103
+ FSE_CTable const* ctable,
104
+ unsigned const* count,
105
+ unsigned const max)
106
+ {
107
+ unsigned const kAccuracyLog = 8;
108
+ size_t cost = 0;
109
+ unsigned s;
110
+ FSE_CState_t cstate;
111
+ FSE_initCState(&cstate, ctable);
112
+ if (ZSTD_getFSEMaxSymbolValue(ctable) < max) {
113
+ DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u",
114
+ ZSTD_getFSEMaxSymbolValue(ctable), max);
115
+ return ERROR(GENERIC);
116
+ }
117
+ for (s = 0; s <= max; ++s) {
118
+ unsigned const tableLog = cstate.stateLog;
119
+ unsigned const badCost = (tableLog + 1) << kAccuracyLog;
120
+ unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
121
+ if (count[s] == 0)
122
+ continue;
123
+ if (bitCost >= badCost) {
124
+ DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s);
125
+ return ERROR(GENERIC);
126
+ }
127
+ cost += (size_t)count[s] * bitCost;
128
+ }
129
+ return cost >> kAccuracyLog;
130
+ }
131
+
132
+ /**
133
+ * Returns the cost in bits of encoding the distribution in count using the
134
+ * table described by norm. The max symbol support by norm is assumed >= max.
135
+ * norm must be valid for every symbol with non-zero probability in count.
136
+ */
137
+ size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
138
+ unsigned const* count, unsigned const max)
139
+ {
140
+ unsigned const shift = 8 - accuracyLog;
141
+ size_t cost = 0;
142
+ unsigned s;
143
+ assert(accuracyLog <= 8);
144
+ for (s = 0; s <= max; ++s) {
145
+ unsigned const normAcc = (norm[s] != -1) ? (unsigned)norm[s] : 1;
146
+ unsigned const norm256 = normAcc << shift;
147
+ assert(norm256 > 0);
148
+ assert(norm256 < 256);
149
+ cost += count[s] * kInverseProbabilityLog256[norm256];
150
+ }
151
+ return cost >> 8;
152
+ }
153
+
154
+ symbolEncodingType_e
155
+ ZSTD_selectEncodingType(
156
+ FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
157
+ size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
158
+ FSE_CTable const* prevCTable,
159
+ short const* defaultNorm, U32 defaultNormLog,
160
+ ZSTD_defaultPolicy_e const isDefaultAllowed,
161
+ ZSTD_strategy const strategy)
162
+ {
163
+ ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
164
+ if (mostFrequent == nbSeq) {
165
+ *repeatMode = FSE_repeat_none;
166
+ if (isDefaultAllowed && nbSeq <= 2) {
167
+ /* Prefer set_basic over set_rle when there are 2 or less symbols,
168
+ * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
169
+ * If basic encoding isn't possible, always choose RLE.
170
+ */
171
+ DEBUGLOG(5, "Selected set_basic");
172
+ return set_basic;
173
+ }
174
+ DEBUGLOG(5, "Selected set_rle");
175
+ return set_rle;
176
+ }
177
+ if (strategy < ZSTD_lazy) {
178
+ if (isDefaultAllowed) {
179
+ size_t const staticFse_nbSeq_max = 1000;
180
+ size_t const mult = 10 - strategy;
181
+ size_t const baseLog = 3;
182
+ size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */
183
+ assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */
184
+ assert(mult <= 9 && mult >= 7);
185
+ if ( (*repeatMode == FSE_repeat_valid)
186
+ && (nbSeq < staticFse_nbSeq_max) ) {
187
+ DEBUGLOG(5, "Selected set_repeat");
188
+ return set_repeat;
189
+ }
190
+ if ( (nbSeq < dynamicFse_nbSeq_min)
191
+ || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {
192
+ DEBUGLOG(5, "Selected set_basic");
193
+ /* The format allows default tables to be repeated, but it isn't useful.
194
+ * When using simple heuristics to select encoding type, we don't want
195
+ * to confuse these tables with dictionaries. When running more careful
196
+ * analysis, we don't need to waste time checking both repeating tables
197
+ * and default tables.
198
+ */
199
+ *repeatMode = FSE_repeat_none;
200
+ return set_basic;
201
+ }
202
+ }
203
+ } else {
204
+ size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);
205
+ size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);
206
+ size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);
207
+ size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);
208
+
209
+ if (isDefaultAllowed) {
210
+ assert(!ZSTD_isError(basicCost));
211
+ assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
212
+ }
213
+ assert(!ZSTD_isError(NCountCost));
214
+ assert(compressedCost < ERROR(maxCode));
215
+ DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
216
+ (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost);
217
+ if (basicCost <= repeatCost && basicCost <= compressedCost) {
218
+ DEBUGLOG(5, "Selected set_basic");
219
+ assert(isDefaultAllowed);
220
+ *repeatMode = FSE_repeat_none;
221
+ return set_basic;
222
+ }
223
+ if (repeatCost <= compressedCost) {
224
+ DEBUGLOG(5, "Selected set_repeat");
225
+ assert(!ZSTD_isError(repeatCost));
226
+ return set_repeat;
227
+ }
228
+ assert(compressedCost < basicCost && compressedCost < repeatCost);
229
+ }
230
+ DEBUGLOG(5, "Selected set_compressed");
231
+ *repeatMode = FSE_repeat_check;
232
+ return set_compressed;
233
+ }
234
+
235
+ size_t
236
+ ZSTD_buildCTable(void* dst, size_t dstCapacity,
237
+ FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
238
+ unsigned* count, U32 max,
239
+ const BYTE* codeTable, size_t nbSeq,
240
+ const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
241
+ const FSE_CTable* prevCTable, size_t prevCTableSize,
242
+ void* entropyWorkspace, size_t entropyWorkspaceSize)
243
+ {
244
+ BYTE* op = (BYTE*)dst;
245
+ const BYTE* const oend = op + dstCapacity;
246
+ DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity);
247
+
248
+ switch (type) {
249
+ case set_rle:
250
+ FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max), "");
251
+ RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall, "not enough space");
252
+ *op = codeTable[0];
253
+ return 1;
254
+ case set_repeat:
255
+ ZSTD_memcpy(nextCTable, prevCTable, prevCTableSize);
256
+ return 0;
257
+ case set_basic:
258
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */
259
+ return 0;
260
+ case set_compressed: {
261
+ S16 norm[MaxSeq + 1];
262
+ size_t nbSeq_1 = nbSeq;
263
+ const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
264
+ if (count[codeTable[nbSeq-1]] > 1) {
265
+ count[codeTable[nbSeq-1]]--;
266
+ nbSeq_1--;
267
+ }
268
+ assert(nbSeq_1 > 1);
269
+ assert(entropyWorkspaceSize >= FSE_BUILD_CTABLE_WORKSPACE_SIZE(MaxSeq, MaxFSELog));
270
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
271
+ { size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
272
+ FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
273
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), "");
274
+ return NCountSize;
275
+ }
276
+ }
277
+ default: assert(0); RETURN_ERROR(GENERIC, "impossible to reach");
278
+ }
279
+ }
280
+
281
+ FORCE_INLINE_TEMPLATE size_t
282
+ ZSTD_encodeSequences_body(
283
+ void* dst, size_t dstCapacity,
284
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
285
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
286
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
287
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
288
+ {
289
+ BIT_CStream_t blockStream;
290
+ FSE_CState_t stateMatchLength;
291
+ FSE_CState_t stateOffsetBits;
292
+ FSE_CState_t stateLitLength;
293
+
294
+ RETURN_ERROR_IF(
295
+ ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity)),
296
+ dstSize_tooSmall, "not enough space remaining");
297
+ DEBUGLOG(6, "available space for bitstream : %i (dstCapacity=%u)",
298
+ (int)(blockStream.endPtr - blockStream.startPtr),
299
+ (unsigned)dstCapacity);
300
+
301
+ /* first symbols */
302
+ FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
303
+ FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]);
304
+ FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]);
305
+ BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
306
+ if (MEM_32bits()) BIT_flushBits(&blockStream);
307
+ BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
308
+ if (MEM_32bits()) BIT_flushBits(&blockStream);
309
+ if (longOffsets) {
310
+ U32 const ofBits = ofCodeTable[nbSeq-1];
311
+ unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
312
+ if (extraBits) {
313
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
314
+ BIT_flushBits(&blockStream);
315
+ }
316
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
317
+ ofBits - extraBits);
318
+ } else {
319
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
320
+ }
321
+ BIT_flushBits(&blockStream);
322
+
323
+ { size_t n;
324
+ for (n=nbSeq-2 ; n<nbSeq ; n--) { /* intentional underflow */
325
+ BYTE const llCode = llCodeTable[n];
326
+ BYTE const ofCode = ofCodeTable[n];
327
+ BYTE const mlCode = mlCodeTable[n];
328
+ U32 const llBits = LL_bits[llCode];
329
+ U32 const ofBits = ofCode;
330
+ U32 const mlBits = ML_bits[mlCode];
331
+ DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
332
+ (unsigned)sequences[n].litLength,
333
+ (unsigned)sequences[n].matchLength + MINMATCH,
334
+ (unsigned)sequences[n].offset);
335
+ /* 32b*/ /* 64b*/
336
+ /* (7)*/ /* (7)*/
337
+ FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
338
+ FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
339
+ if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
340
+ FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */
341
+ if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
342
+ BIT_flushBits(&blockStream); /* (7)*/
343
+ BIT_addBits(&blockStream, sequences[n].litLength, llBits);
344
+ if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
345
+ BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
346
+ if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);
347
+ if (longOffsets) {
348
+ unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
349
+ if (extraBits) {
350
+ BIT_addBits(&blockStream, sequences[n].offset, extraBits);
351
+ BIT_flushBits(&blockStream); /* (7)*/
352
+ }
353
+ BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
354
+ ofBits - extraBits); /* 31 */
355
+ } else {
356
+ BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */
357
+ }
358
+ BIT_flushBits(&blockStream); /* (7)*/
359
+ DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr));
360
+ } }
361
+
362
+ DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
363
+ FSE_flushCState(&blockStream, &stateMatchLength);
364
+ DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
365
+ FSE_flushCState(&blockStream, &stateOffsetBits);
366
+ DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog);
367
+ FSE_flushCState(&blockStream, &stateLitLength);
368
+
369
+ { size_t const streamSize = BIT_closeCStream(&blockStream);
370
+ RETURN_ERROR_IF(streamSize==0, dstSize_tooSmall, "not enough space");
371
+ return streamSize;
372
+ }
373
+ }
374
+
375
+ static size_t
376
+ ZSTD_encodeSequences_default(
377
+ void* dst, size_t dstCapacity,
378
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
379
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
380
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
381
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
382
+ {
383
+ return ZSTD_encodeSequences_body(dst, dstCapacity,
384
+ CTable_MatchLength, mlCodeTable,
385
+ CTable_OffsetBits, ofCodeTable,
386
+ CTable_LitLength, llCodeTable,
387
+ sequences, nbSeq, longOffsets);
388
+ }
389
+
390
+
391
+ #if DYNAMIC_BMI2
392
+
393
+ static TARGET_ATTRIBUTE("bmi2") size_t
394
+ ZSTD_encodeSequences_bmi2(
395
+ void* dst, size_t dstCapacity,
396
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
397
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
398
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
399
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
400
+ {
401
+ return ZSTD_encodeSequences_body(dst, dstCapacity,
402
+ CTable_MatchLength, mlCodeTable,
403
+ CTable_OffsetBits, ofCodeTable,
404
+ CTable_LitLength, llCodeTable,
405
+ sequences, nbSeq, longOffsets);
406
+ }
407
+
408
+ #endif
409
+
410
+ size_t ZSTD_encodeSequences(
411
+ void* dst, size_t dstCapacity,
412
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
413
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
414
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
415
+ seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
416
+ {
417
+ DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity);
418
+ #if DYNAMIC_BMI2
419
+ if (bmi2) {
420
+ return ZSTD_encodeSequences_bmi2(dst, dstCapacity,
421
+ CTable_MatchLength, mlCodeTable,
422
+ CTable_OffsetBits, ofCodeTable,
423
+ CTable_LitLength, llCodeTable,
424
+ sequences, nbSeq, longOffsets);
425
+ }
426
+ #endif
427
+ (void)bmi2;
428
+ return ZSTD_encodeSequences_default(dst, dstCapacity,
429
+ CTable_MatchLength, mlCodeTable,
430
+ CTable_OffsetBits, ofCodeTable,
431
+ CTable_LitLength, llCodeTable,
432
+ sequences, nbSeq, longOffsets);
433
+ }