extlz4 0.2.5 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,38 +0,0 @@
1
- dependencies:
2
- override:
3
- - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; sudo apt-get -y -qq update
4
- - sudo apt-get -y install qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu
5
- - sudo apt-get -y install qemu-system-arm gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
6
- - sudo apt-get -y install libc6-dev-i386 clang gcc-5 gcc-5-multilib gcc-6 valgrind
7
-
8
- test:
9
- override:
10
- # Tests compilers and C standards
11
- - clang -v; make clangtest && make clean
12
- - g++ -v; make gpptest && make clean
13
- - gcc -v; make c_standards && make clean
14
- - gcc-5 -v; make -C tests test-lz4 CC=gcc-5 MOREFLAGS=-Werror && make clean
15
- - gcc-5 -v; make -C tests test-lz4c32 CC=gcc-5 MOREFLAGS="-I/usr/include/x86_64-linux-gnu -Werror" && make clean
16
- - gcc-6 -v; make c_standards CC=gcc-6 && make clean
17
- - gcc-6 -v; make -C tests test-lz4 CC=gcc-6 MOREFLAGS=-Werror && make clean
18
- # Shorter tests
19
- - make cmake && make clean
20
- - make -C tests test-lz4
21
- - make -C tests test-lz4c
22
- - make -C tests test-frametest
23
- - make -C tests test-fullbench
24
- - make -C tests test-fuzzer && make clean
25
- - make -C lib all && make clean
26
- - pyenv global 3.4.4; CFLAGS=-I/usr/include/x86_64-linux-gnu make versionsTest && make clean
27
- - make travis-install && make clean
28
- # Longer tests
29
- - gcc -v; make -C tests test32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean
30
- - make usan && make clean
31
- - clang -v; make staticAnalyze && make clean
32
- # Valgrind tests
33
- - make -C tests test-mem && make clean
34
- # ARM, AArch64, PowerPC, PowerPC64 tests
35
- - make platformTest CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static && make clean
36
- - make platformTest CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static MOREFLAGS=-m64 && make clean
37
- - make platformTest CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static && make clean
38
- - make platformTest CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static && make clean
@@ -1,356 +0,0 @@
1
- /*
2
- lz4opt.h - Optimal Mode of LZ4
3
- Copyright (C) 2015-2017, Przemyslaw Skibinski <inikep@gmail.com>
4
- Note : this file is intended to be included within lz4hc.c
5
-
6
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7
-
8
- Redistribution and use in source and binary forms, with or without
9
- modification, are permitted provided that the following conditions are
10
- met:
11
-
12
- * Redistributions of source code must retain the above copyright
13
- notice, this list of conditions and the following disclaimer.
14
- * Redistributions in binary form must reproduce the above
15
- copyright notice, this list of conditions and the following disclaimer
16
- in the documentation and/or other materials provided with the
17
- distribution.
18
-
19
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
-
31
- You can contact the author at :
32
- - LZ4 source repository : https://github.com/lz4/lz4
33
- - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
34
- */
35
-
36
- #define LZ4_OPT_NUM (1<<12)
37
-
38
- typedef struct {
39
- int price;
40
- int off;
41
- int mlen;
42
- int litlen;
43
- } LZ4HC_optimal_t;
44
-
45
-
46
- /* price in bytes */
47
- LZ4_FORCE_INLINE int LZ4HC_literalsPrice(int const litlen)
48
- {
49
- int price = litlen;
50
- if (litlen >= (int)RUN_MASK)
51
- price += 1 + (litlen-RUN_MASK)/255;
52
- return price;
53
- }
54
-
55
-
56
- /* requires mlen >= MINMATCH */
57
- LZ4_FORCE_INLINE int LZ4HC_sequencePrice(int litlen, int mlen)
58
- {
59
- int price = 1 + 2 ; /* token + 16-bit offset */
60
-
61
- price += LZ4HC_literalsPrice(litlen);
62
-
63
- if (mlen >= (int)(ML_MASK+MINMATCH))
64
- price += 1 + (mlen-(ML_MASK+MINMATCH))/255;
65
-
66
- return price;
67
- }
68
-
69
-
70
- /*-*************************************
71
- * Match finder
72
- ***************************************/
73
- typedef struct {
74
- int off;
75
- int len;
76
- } LZ4HC_match_t;
77
-
78
- LZ4_FORCE_INLINE
79
- LZ4HC_match_t LZ4HC_FindLongerMatch(LZ4HC_CCtx_internal* const ctx,
80
- const BYTE* ip, const BYTE* const iHighLimit,
81
- int minLen, int nbSearches)
82
- {
83
- LZ4HC_match_t match = { 0 , 0 };
84
- const BYTE* matchPtr = NULL;
85
- /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos),
86
- * but this won't be the case here, as we define iLowLimit==ip,
87
- * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */
88
- int const matchLength = LZ4HC_InsertAndGetWiderMatch(ctx,
89
- ip, ip, iHighLimit, minLen, &matchPtr, &ip,
90
- nbSearches, 1 /* patternAnalysis */);
91
- if (matchLength <= minLen) return match;
92
- match.len = matchLength;
93
- match.off = (int)(ip-matchPtr);
94
- return match;
95
- }
96
-
97
-
98
- static int LZ4HC_compress_optimal (
99
- LZ4HC_CCtx_internal* ctx,
100
- const char* const source,
101
- char* dst,
102
- int* srcSizePtr,
103
- int dstCapacity,
104
- int const nbSearches,
105
- size_t sufficient_len,
106
- limitedOutput_directive limit,
107
- int const fullUpdate
108
- )
109
- {
110
- #define TRAILING_LITERALS 3
111
- LZ4HC_optimal_t opt[LZ4_OPT_NUM + TRAILING_LITERALS]; /* this uses a bit too much stack memory to my taste ... */
112
-
113
- const BYTE* ip = (const BYTE*) source;
114
- const BYTE* anchor = ip;
115
- const BYTE* const iend = ip + *srcSizePtr;
116
- const BYTE* const mflimit = iend - MFLIMIT;
117
- const BYTE* const matchlimit = iend - LASTLITERALS;
118
- BYTE* op = (BYTE*) dst;
119
- BYTE* opSaved = (BYTE*) dst;
120
- BYTE* oend = op + dstCapacity;
121
-
122
- /* init */
123
- DEBUGLOG(5, "LZ4HC_compress_optimal");
124
- *srcSizePtr = 0;
125
- if (limit == limitedDestSize) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */
126
- if (sufficient_len >= LZ4_OPT_NUM) sufficient_len = LZ4_OPT_NUM-1;
127
-
128
- /* Main Loop */
129
- assert(ip - anchor < LZ4_MAX_INPUT_SIZE);
130
- while (ip < mflimit) {
131
- int const llen = (int)(ip - anchor);
132
- int best_mlen, best_off;
133
- int cur, last_match_pos = 0;
134
-
135
- LZ4HC_match_t const firstMatch = LZ4HC_FindLongerMatch(ctx, ip, matchlimit, MINMATCH-1, nbSearches);
136
- if (firstMatch.len==0) { ip++; continue; }
137
-
138
- if ((size_t)firstMatch.len > sufficient_len) {
139
- /* good enough solution : immediate encoding */
140
- int const firstML = firstMatch.len;
141
- const BYTE* const matchPos = ip - firstMatch.off;
142
- opSaved = op;
143
- if ( LZ4HC_encodeSequence(&ip, &op, &anchor, firstML, matchPos, limit, oend) ) /* updates ip, op and anchor */
144
- goto _dest_overflow;
145
- continue;
146
- }
147
-
148
- /* set prices for first positions (literals) */
149
- { int rPos;
150
- for (rPos = 0 ; rPos < MINMATCH ; rPos++) {
151
- int const cost = LZ4HC_literalsPrice(llen + rPos);
152
- opt[rPos].mlen = 1;
153
- opt[rPos].off = 0;
154
- opt[rPos].litlen = llen + rPos;
155
- opt[rPos].price = cost;
156
- DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup",
157
- rPos, cost, opt[rPos].litlen);
158
- } }
159
- /* set prices using initial match */
160
- { int mlen = MINMATCH;
161
- int const matchML = firstMatch.len; /* necessarily < sufficient_len < LZ4_OPT_NUM */
162
- int const offset = firstMatch.off;
163
- assert(matchML < LZ4_OPT_NUM);
164
- for ( ; mlen <= matchML ; mlen++) {
165
- int const cost = LZ4HC_sequencePrice(llen, mlen);
166
- opt[mlen].mlen = mlen;
167
- opt[mlen].off = offset;
168
- opt[mlen].litlen = llen;
169
- opt[mlen].price = cost;
170
- DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i) -- initial setup",
171
- mlen, cost, mlen);
172
- } }
173
- last_match_pos = firstMatch.len;
174
- { int addLit;
175
- for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) {
176
- opt[last_match_pos+addLit].mlen = 1; /* literal */
177
- opt[last_match_pos+addLit].off = 0;
178
- opt[last_match_pos+addLit].litlen = addLit;
179
- opt[last_match_pos+addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit);
180
- DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup",
181
- last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit);
182
- } }
183
-
184
- /* check further positions */
185
- for (cur = 1; cur < last_match_pos; cur++) {
186
- const BYTE* const curPtr = ip + cur;
187
- LZ4HC_match_t newMatch;
188
-
189
- if (curPtr >= mflimit) break;
190
- DEBUGLOG(7, "rPos:%u[%u] vs [%u]%u",
191
- cur, opt[cur].price, opt[cur+1].price, cur+1);
192
- if (fullUpdate) {
193
- /* not useful to search here if next position has same (or lower) cost */
194
- if ( (opt[cur+1].price <= opt[cur].price)
195
- /* in some cases, next position has same cost, but cost rises sharply after, so a small match would still be beneficial */
196
- && (opt[cur+MINMATCH].price < opt[cur].price + 3/*min seq price*/) )
197
- continue;
198
- } else {
199
- /* not useful to search here if next position has same (or lower) cost */
200
- if (opt[cur+1].price <= opt[cur].price) continue;
201
- }
202
-
203
- DEBUGLOG(7, "search at rPos:%u", cur);
204
- if (fullUpdate)
205
- newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, MINMATCH-1, nbSearches);
206
- else
207
- /* only test matches of minimum length; slightly faster, but misses a few bytes */
208
- newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, last_match_pos - cur, nbSearches);
209
- if (!newMatch.len) continue;
210
-
211
- if ( ((size_t)newMatch.len > sufficient_len)
212
- || (newMatch.len + cur >= LZ4_OPT_NUM) ) {
213
- /* immediate encoding */
214
- best_mlen = newMatch.len;
215
- best_off = newMatch.off;
216
- last_match_pos = cur + 1;
217
- goto encode;
218
- }
219
-
220
- /* before match : set price with literals at beginning */
221
- { int const baseLitlen = opt[cur].litlen;
222
- int litlen;
223
- for (litlen = 1; litlen < MINMATCH; litlen++) {
224
- int const price = opt[cur].price - LZ4HC_literalsPrice(baseLitlen) + LZ4HC_literalsPrice(baseLitlen+litlen);
225
- int const pos = cur + litlen;
226
- if (price < opt[pos].price) {
227
- opt[pos].mlen = 1; /* literal */
228
- opt[pos].off = 0;
229
- opt[pos].litlen = baseLitlen+litlen;
230
- opt[pos].price = price;
231
- DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)",
232
- pos, price, opt[pos].litlen);
233
- } } }
234
-
235
- /* set prices using match at position = cur */
236
- { int const matchML = newMatch.len;
237
- int ml = MINMATCH;
238
-
239
- assert(cur + newMatch.len < LZ4_OPT_NUM);
240
- for ( ; ml <= matchML ; ml++) {
241
- int const pos = cur + ml;
242
- int const offset = newMatch.off;
243
- int price;
244
- int ll;
245
- DEBUGLOG(7, "testing price rPos %i (last_match_pos=%i)",
246
- pos, last_match_pos);
247
- if (opt[cur].mlen == 1) {
248
- ll = opt[cur].litlen;
249
- price = ((cur > ll) ? opt[cur - ll].price : 0)
250
- + LZ4HC_sequencePrice(ll, ml);
251
- } else {
252
- ll = 0;
253
- price = opt[cur].price + LZ4HC_sequencePrice(0, ml);
254
- }
255
-
256
- if (pos > last_match_pos+TRAILING_LITERALS || price <= opt[pos].price) {
257
- DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i)",
258
- pos, price, ml);
259
- assert(pos < LZ4_OPT_NUM);
260
- if ( (ml == matchML) /* last pos of last match */
261
- && (last_match_pos < pos) )
262
- last_match_pos = pos;
263
- opt[pos].mlen = ml;
264
- opt[pos].off = offset;
265
- opt[pos].litlen = ll;
266
- opt[pos].price = price;
267
- } } }
268
- /* complete following positions with literals */
269
- { int addLit;
270
- for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) {
271
- opt[last_match_pos+addLit].mlen = 1; /* literal */
272
- opt[last_match_pos+addLit].off = 0;
273
- opt[last_match_pos+addLit].litlen = addLit;
274
- opt[last_match_pos+addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit);
275
- DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)", last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit);
276
- } }
277
- } /* for (cur = 1; cur <= last_match_pos; cur++) */
278
-
279
- best_mlen = opt[last_match_pos].mlen;
280
- best_off = opt[last_match_pos].off;
281
- cur = last_match_pos - best_mlen;
282
-
283
- encode: /* cur, last_match_pos, best_mlen, best_off must be set */
284
- assert(cur < LZ4_OPT_NUM);
285
- assert(last_match_pos >= 1); /* == 1 when only one candidate */
286
- DEBUGLOG(6, "reverse traversal, looking for shortest path")
287
- DEBUGLOG(6, "last_match_pos = %i", last_match_pos);
288
- { int candidate_pos = cur;
289
- int selected_matchLength = best_mlen;
290
- int selected_offset = best_off;
291
- while (1) { /* from end to beginning */
292
- int const next_matchLength = opt[candidate_pos].mlen; /* can be 1, means literal */
293
- int const next_offset = opt[candidate_pos].off;
294
- DEBUGLOG(6, "pos %i: sequence length %i", candidate_pos, selected_matchLength);
295
- opt[candidate_pos].mlen = selected_matchLength;
296
- opt[candidate_pos].off = selected_offset;
297
- selected_matchLength = next_matchLength;
298
- selected_offset = next_offset;
299
- if (next_matchLength > candidate_pos) break; /* last match elected, first match to encode */
300
- assert(next_matchLength > 0); /* can be 1, means literal */
301
- candidate_pos -= next_matchLength;
302
- } }
303
-
304
- /* encode all recorded sequences in order */
305
- { int rPos = 0; /* relative position (to ip) */
306
- while (rPos < last_match_pos) {
307
- int const ml = opt[rPos].mlen;
308
- int const offset = opt[rPos].off;
309
- if (ml == 1) { ip++; rPos++; continue; } /* literal; note: can end up with several literals, in which case, skip them */
310
- rPos += ml;
311
- assert(ml >= MINMATCH);
312
- assert((offset >= 1) && (offset <= MAX_DISTANCE));
313
- opSaved = op;
314
- if ( LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ip - offset, limit, oend) ) /* updates ip, op and anchor */
315
- goto _dest_overflow;
316
- } }
317
- } /* while (ip < mflimit) */
318
-
319
- _last_literals:
320
- /* Encode Last Literals */
321
- { size_t lastRunSize = (size_t)(iend - anchor); /* literals */
322
- size_t litLength = (lastRunSize + 255 - RUN_MASK) / 255;
323
- size_t const totalSize = 1 + litLength + lastRunSize;
324
- if (limit == limitedDestSize) oend += LASTLITERALS; /* restore correct value */
325
- if (limit && (op + totalSize > oend)) {
326
- if (limit == limitedOutput) return 0; /* Check output limit */
327
- /* adapt lastRunSize to fill 'dst' */
328
- lastRunSize = (size_t)(oend - op) - 1;
329
- litLength = (lastRunSize + 255 - RUN_MASK) / 255;
330
- lastRunSize -= litLength;
331
- }
332
- ip = anchor + lastRunSize;
333
-
334
- if (lastRunSize >= RUN_MASK) {
335
- size_t accumulator = lastRunSize - RUN_MASK;
336
- *op++ = (RUN_MASK << ML_BITS);
337
- for(; accumulator >= 255 ; accumulator -= 255) *op++ = 255;
338
- *op++ = (BYTE) accumulator;
339
- } else {
340
- *op++ = (BYTE)(lastRunSize << ML_BITS);
341
- }
342
- memcpy(op, anchor, lastRunSize);
343
- op += lastRunSize;
344
- }
345
-
346
- /* End */
347
- *srcSizePtr = (int) (((const char*)ip) - source);
348
- return (int) ((char*)op-dst);
349
-
350
- _dest_overflow:
351
- if (limit == limitedDestSize) {
352
- op = opSaved; /* restore correct out pointer */
353
- goto _last_literals;
354
- }
355
- return 0;
356
- }