1pub type ZSTD_longLengthType_e = core::ffi::c_uint;
2pub const ZSTD_llt_matchLength: ZSTD_longLengthType_e = 2;
3pub const ZSTD_llt_literalLength: ZSTD_longLengthType_e = 1;
4pub const ZSTD_llt_none: ZSTD_longLengthType_e = 0;
5#[repr(C)]
6pub struct optState_t {
7 pub litFreq: *mut core::ffi::c_uint,
8 pub litLengthFreq: *mut core::ffi::c_uint,
9 pub matchLengthFreq: *mut core::ffi::c_uint,
10 pub offCodeFreq: *mut core::ffi::c_uint,
11 pub matchTable: *mut ZSTD_match_t,
12 pub priceTable: *mut ZSTD_optimal_t,
13 pub litSum: u32,
14 pub litLengthSum: u32,
15 pub matchLengthSum: u32,
16 pub offCodeSum: u32,
17 pub litSumBasePrice: u32,
18 pub litLengthSumBasePrice: u32,
19 pub matchLengthSumBasePrice: u32,
20 pub offCodeSumBasePrice: u32,
21 pub priceType: ZSTD_OptPrice_e,
22 pub symbolCosts: *const ZSTD_entropyCTables_t,
23 pub literalCompressionMode: ZSTD_ParamSwitch_e,
24}
25pub type ZSTD_ParamSwitch_e = core::ffi::c_uint;
26pub const ZSTD_ps_disable: ZSTD_ParamSwitch_e = 2;
27pub const ZSTD_ps_enable: ZSTD_ParamSwitch_e = 1;
28pub const ZSTD_ps_auto: ZSTD_ParamSwitch_e = 0;
29#[repr(C)]
30pub struct ZSTD_entropyCTables_t {
31 pub huf: ZSTD_hufCTables_t,
32 pub fse: ZSTD_fseCTables_t,
33}
34#[repr(C)]
35pub struct ZSTD_fseCTables_t {
36 pub offcodeCTable: [FSE_CTable; 193],
37 pub matchlengthCTable: [FSE_CTable; 363],
38 pub litlengthCTable: [FSE_CTable; 329],
39 pub offcode_repeatMode: FSE_repeat,
40 pub matchlength_repeatMode: FSE_repeat,
41 pub litlength_repeatMode: FSE_repeat,
42}
43#[repr(C)]
44pub struct ZSTD_hufCTables_t {
45 pub CTable: [HUF_CElt; 257],
46 pub repeatMode: HUF_repeat,
47}
48pub type ZSTD_OptPrice_e = core::ffi::c_uint;
49pub const zop_predef: ZSTD_OptPrice_e = 1;
50pub const zop_dynamic: ZSTD_OptPrice_e = 0;
51#[repr(C)]
52pub struct ZSTD_match_t {
53 pub off: u32,
54 pub len: u32,
55}
56#[derive(Copy, Clone)]
57#[repr(C)]
58pub struct ldmState_t {
59 pub window: ZSTD_window_t,
60 pub hashTable: *mut ldmEntry_t,
61 pub loadedDictEnd: u32,
62 pub bucketOffsets: *mut u8,
63 pub splitIndices: [size_t; 64],
64 pub matchCandidates: [ldmMatchCandidate_t; 64],
65}
66#[derive(Copy, Clone)]
67#[repr(C)]
68pub struct ldmMatchCandidate_t {
69 pub split: *const u8,
70 pub hash: u32,
71 pub checksum: u32,
72 pub bucket: *mut ldmEntry_t,
73}
74#[derive(Copy, Clone)]
75#[repr(C)]
76pub struct ldmEntry_t {
77 pub offset: u32,
78 pub checksum: u32,
79}
80#[derive(Copy, Clone)]
81#[repr(C)]
82pub struct ldmParams_t {
83 pub enableLdm: ZSTD_ParamSwitch_e,
84 pub hashLog: u32,
85 pub bucketSizeLog: u32,
86 pub minMatchLength: u32,
87 pub hashRateLog: u32,
88 pub windowLog: u32,
89}
90pub type ZSTD_dictTableLoadMethod_e = core::ffi::c_uint;
91pub const ZSTD_dtlm_full: ZSTD_dictTableLoadMethod_e = 1;
92pub const ZSTD_dtlm_fast: ZSTD_dictTableLoadMethod_e = 0;
93pub type ZSTD_tableFillPurpose_e = core::ffi::c_uint;
94pub const ZSTD_tfp_forCDict: ZSTD_tableFillPurpose_e = 1;
95pub const ZSTD_tfp_forCCtx: ZSTD_tableFillPurpose_e = 0;
96pub type ZSTD_dictMode_e = core::ffi::c_uint;
97pub const ZSTD_dedicatedDictSearch: ZSTD_dictMode_e = 3;
98pub const ZSTD_dictMatchState: ZSTD_dictMode_e = 2;
99pub const ZSTD_extDict: ZSTD_dictMode_e = 1;
100pub const ZSTD_noDict: ZSTD_dictMode_e = 0;
101pub type ZSTD_BlockCompressor_f = Option<
102 unsafe fn(
103 *mut ZSTD_MatchState_t,
104 *mut SeqStore_t,
105 *mut u32,
106 *const core::ffi::c_void,
107 size_t,
108 ) -> size_t,
109>;
110#[repr(C)]
111pub struct ldmRollingHashState_t {
112 pub rolling: u64,
113 pub stopMask: u64,
114}
115
116use libc::size_t;
117
118use crate::lib::common::error_private::{ERR_isError, Error};
119use crate::lib::common::fse::{FSE_CTable, FSE_repeat};
120use crate::lib::common::huf::{HUF_CElt, HUF_repeat};
121use crate::lib::common::mem::{MEM_64bits, MEM_isLittleEndian, MEM_read16, MEM_read32, MEM_readST};
122use crate::lib::common::xxhash::ZSTD_XXH64;
123use crate::lib::common::zstd_internal::{
124 Overlap, ZSTD_copy16, ZSTD_wildcopy, MINMATCH, WILDCOPY_OVERLENGTH, ZSTD_REP_NUM,
125};
126use crate::lib::compress::zstd_compress::{
127 rawSeq, RawSeqStore_t, SeqStore_t, ZSTD_MatchState_t, ZSTD_optimal_t,
128 ZSTD_selectBlockCompressor, ZSTD_window_t,
129};
130use crate::lib::compress::zstd_double_fast::ZSTD_fillDoubleHashTable;
131use crate::lib::compress::zstd_fast::ZSTD_fillHashTable;
132use crate::lib::zstd::*;
133pub const HASH_READ_SIZE: core::ffi::c_int = 8;
134pub const ZSTD_WINDOW_START_INDEX: core::ffi::c_int = 2;
135pub const LDM_BATCH_SIZE: core::ffi::c_int = 64;
136unsafe fn ZSTD_safecopyLiterals(
137 mut op: *mut u8,
138 mut ip: *const u8,
139 iend: *const u8,
140 ilimit_w: *const u8,
141) {
142 if ip <= ilimit_w {
143 ZSTD_wildcopy(
144 op as *mut core::ffi::c_void,
145 ip as *const core::ffi::c_void,
146 ilimit_w.offset_from(ip) as size_t,
147 Overlap::NoOverlap,
148 );
149 op = op.offset(ilimit_w.offset_from(ip) as core::ffi::c_long as isize);
150 ip = ilimit_w;
151 }
152 while ip < iend {
153 let fresh0 = ip;
154 ip = ip.offset(1);
155 let fresh1 = op;
156 op = op.offset(1);
157 *fresh1 = *fresh0;
158 }
159}
160#[inline(always)]
161unsafe fn ZSTD_storeSeqOnly(
162 seqStorePtr: *mut SeqStore_t,
163 litLength: size_t,
164 offBase: u32,
165 matchLength: size_t,
166) {
167 if (litLength > 0xffff as core::ffi::c_int as size_t) as core::ffi::c_int as core::ffi::c_long
168 != 0
169 {
170 (*seqStorePtr).longLengthType = ZSTD_llt_literalLength;
171 (*seqStorePtr).longLengthPos = ((*seqStorePtr).sequences)
172 .offset_from((*seqStorePtr).sequencesStart)
173 as core::ffi::c_long as u32;
174 }
175 (*((*seqStorePtr).sequences).offset(0)).litLength = litLength as u16;
176 (*((*seqStorePtr).sequences).offset(0)).offBase = offBase;
177 let mlBase = matchLength.wrapping_sub(MINMATCH as size_t);
178 if (mlBase > 0xffff as core::ffi::c_int as size_t) as core::ffi::c_int as core::ffi::c_long != 0
179 {
180 (*seqStorePtr).longLengthType = ZSTD_llt_matchLength;
181 (*seqStorePtr).longLengthPos = ((*seqStorePtr).sequences)
182 .offset_from((*seqStorePtr).sequencesStart)
183 as core::ffi::c_long as u32;
184 }
185 (*((*seqStorePtr).sequences).offset(0)).mlBase = mlBase as u16;
186 (*seqStorePtr).sequences = ((*seqStorePtr).sequences).offset(1);
187 (*seqStorePtr).sequences;
188}
189#[inline(always)]
190unsafe fn ZSTD_storeSeq(
191 seqStorePtr: *mut SeqStore_t,
192 litLength: size_t,
193 literals: *const u8,
194 litLimit: *const u8,
195 offBase: u32,
196 matchLength: size_t,
197) {
198 let litLimit_w = litLimit.sub(WILDCOPY_OVERLENGTH);
199 let litEnd = literals.add(litLength);
200 if litEnd <= litLimit_w {
201 ZSTD_copy16(
202 (*seqStorePtr).lit as *mut core::ffi::c_void,
203 literals as *const core::ffi::c_void,
204 );
205 if litLength > 16 {
206 ZSTD_wildcopy(
207 ((*seqStorePtr).lit).offset(16) as *mut core::ffi::c_void,
208 literals.offset(16) as *const core::ffi::c_void,
209 litLength.wrapping_sub(16),
210 Overlap::NoOverlap,
211 );
212 }
213 } else {
214 ZSTD_safecopyLiterals((*seqStorePtr).lit, literals, litEnd, litLimit_w);
215 }
216 (*seqStorePtr).lit = ((*seqStorePtr).lit).add(litLength);
217 ZSTD_storeSeqOnly(seqStorePtr, litLength, offBase, matchLength);
218}
219#[inline]
220unsafe fn ZSTD_count(mut pIn: *const u8, mut pMatch: *const u8, pInLimit: *const u8) -> size_t {
221 let pStart = pIn;
222 let pInLoopLimit = pInLimit.offset(
223 -((::core::mem::size_of::<size_t>() as core::ffi::c_ulong).wrapping_sub(1) as isize),
224 );
225 if pIn < pInLoopLimit {
226 let diff = MEM_readST(pMatch as *const core::ffi::c_void)
227 ^ MEM_readST(pIn as *const core::ffi::c_void);
228 if diff != 0 {
229 return ZSTD_NbCommonBytes(diff) as size_t;
230 }
231 pIn = pIn.offset(::core::mem::size_of::<size_t>() as core::ffi::c_ulong as isize);
232 pMatch = pMatch.offset(::core::mem::size_of::<size_t>() as core::ffi::c_ulong as isize);
233 while pIn < pInLoopLimit {
234 let diff_0 = MEM_readST(pMatch as *const core::ffi::c_void)
235 ^ MEM_readST(pIn as *const core::ffi::c_void);
236 if diff_0 == 0 {
237 pIn = pIn.offset(::core::mem::size_of::<size_t>() as core::ffi::c_ulong as isize);
238 pMatch =
239 pMatch.offset(::core::mem::size_of::<size_t>() as core::ffi::c_ulong as isize);
240 } else {
241 pIn = pIn.offset(ZSTD_NbCommonBytes(diff_0) as isize);
242 return pIn.offset_from(pStart) as size_t;
243 }
244 }
245 }
246 if MEM_64bits() != 0
247 && pIn < pInLimit.offset(-(3))
248 && MEM_read32(pMatch as *const core::ffi::c_void)
249 == MEM_read32(pIn as *const core::ffi::c_void)
250 {
251 pIn = pIn.offset(4);
252 pMatch = pMatch.offset(4);
253 }
254 if pIn < pInLimit.offset(-(1))
255 && MEM_read16(pMatch as *const core::ffi::c_void) as core::ffi::c_int
256 == MEM_read16(pIn as *const core::ffi::c_void) as core::ffi::c_int
257 {
258 pIn = pIn.offset(2);
259 pMatch = pMatch.offset(2);
260 }
261 if pIn < pInLimit && *pMatch as core::ffi::c_int == *pIn as core::ffi::c_int {
262 pIn = pIn.offset(1);
263 }
264 pIn.offset_from(pStart) as size_t
265}
266#[inline]
267unsafe fn ZSTD_count_2segments(
268 ip: *const u8,
269 match_0: *const u8,
270 iEnd: *const u8,
271 mEnd: *const u8,
272 iStart: *const u8,
273) -> size_t {
274 let vEnd = if ip.offset(mEnd.offset_from(match_0) as core::ffi::c_long as isize) < iEnd {
275 ip.offset(mEnd.offset_from(match_0) as core::ffi::c_long as isize)
276 } else {
277 iEnd
278 };
279 let matchLength = ZSTD_count(ip, match_0, vEnd);
280 if match_0.add(matchLength) != mEnd {
281 return matchLength;
282 }
283 matchLength.wrapping_add(ZSTD_count(ip.add(matchLength), iStart, iEnd))
284}
285#[inline]
286unsafe fn ZSTD_window_hasExtDict(window: ZSTD_window_t) -> u32 {
287 (window.lowLimit < window.dictLimit) as core::ffi::c_int as u32
288}
289#[inline]
290unsafe fn ZSTD_matchState_dictMode(ms: *const ZSTD_MatchState_t) -> ZSTD_dictMode_e {
291 (if ZSTD_window_hasExtDict((*ms).window) != 0 {
292 ZSTD_extDict as core::ffi::c_int
293 } else if !((*ms).dictMatchState).is_null() {
294 if (*(*ms).dictMatchState).dedicatedDictSearch != 0 {
295 ZSTD_dedicatedDictSearch as core::ffi::c_int
296 } else {
297 ZSTD_dictMatchState as core::ffi::c_int
298 }
299 } else {
300 ZSTD_noDict as core::ffi::c_int
301 }) as ZSTD_dictMode_e
302}
303pub const ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY: core::ffi::c_int = 0;
304#[inline]
305unsafe fn ZSTD_window_canOverflowCorrect(
306 window: ZSTD_window_t,
307 cycleLog: u32,
308 maxDist: u32,
309 loadedDictEnd: u32,
310 src: *const core::ffi::c_void,
311) -> u32 {
312 let cycleSize = (1 as core::ffi::c_uint) << cycleLog;
313 let curr = (src as *const u8).offset_from(window.base) as core::ffi::c_long as u32;
314 let minIndexToOverflowCorrect = cycleSize
315 .wrapping_add(if maxDist > cycleSize {
316 maxDist
317 } else {
318 cycleSize
319 })
320 .wrapping_add(ZSTD_WINDOW_START_INDEX as u32);
321 let adjustment = (window.nbOverflowCorrections).wrapping_add(1);
322 let adjustedIndex = if minIndexToOverflowCorrect * adjustment > minIndexToOverflowCorrect {
323 minIndexToOverflowCorrect * adjustment
324 } else {
325 minIndexToOverflowCorrect
326 };
327 let indexLargeEnough = (curr > adjustedIndex) as core::ffi::c_int as u32;
328 let dictionaryInvalidated =
329 (curr > maxDist.wrapping_add(loadedDictEnd)) as core::ffi::c_int as u32;
330 (indexLargeEnough != 0 && dictionaryInvalidated != 0) as core::ffi::c_int as u32
331}
332#[inline]
333unsafe fn ZSTD_window_needOverflowCorrection(
334 window: ZSTD_window_t,
335 cycleLog: u32,
336 maxDist: u32,
337 loadedDictEnd: u32,
338 src: *const core::ffi::c_void,
339 srcEnd: *const core::ffi::c_void,
340) -> u32 {
341 let curr = (srcEnd as *const u8).offset_from(window.base) as core::ffi::c_long as u32;
342 if ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY != 0 {
343 if ZSTD_window_canOverflowCorrect(window, cycleLog, maxDist, loadedDictEnd, src) != 0 {
344 return 1;
345 }
346 }
347 (curr
348 > (if MEM_64bits() != 0 {
349 (3500 as core::ffi::c_uint)
350 .wrapping_mul(((1 as core::ffi::c_int) << 20) as core::ffi::c_uint)
351 } else {
352 (2000 as core::ffi::c_uint)
353 .wrapping_mul(((1 as core::ffi::c_int) << 20) as core::ffi::c_uint)
354 })) as core::ffi::c_int as u32
355}
356#[inline]
357unsafe fn ZSTD_window_correctOverflow(
358 window: *mut ZSTD_window_t,
359 cycleLog: u32,
360 maxDist: u32,
361 src: *const core::ffi::c_void,
362) -> u32 {
363 let cycleSize = (1 as core::ffi::c_uint) << cycleLog;
364 let cycleMask = cycleSize.wrapping_sub(1);
365 let curr = (src as *const u8).offset_from((*window).base) as core::ffi::c_long as u32;
366 let currentCycle = curr & cycleMask;
367 let currentCycleCorrection = if currentCycle < ZSTD_WINDOW_START_INDEX as u32 {
368 if cycleSize > 2 {
369 cycleSize
370 } else {
371 2
372 }
373 } else {
374 0
375 };
376 let newCurrent = currentCycle
377 .wrapping_add(currentCycleCorrection)
378 .wrapping_add(if maxDist > cycleSize {
379 maxDist
380 } else {
381 cycleSize
382 });
383 let correction = curr.wrapping_sub(newCurrent);
384 if ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY == 0 {
385 assert!(correction > 1 << 28);
387 }
388 (*window).base = ((*window).base).offset(correction as isize);
389 (*window).dictBase = ((*window).dictBase).offset(correction as isize);
390 if (*window).lowLimit < correction.wrapping_add(ZSTD_WINDOW_START_INDEX as u32) {
391 (*window).lowLimit = ZSTD_WINDOW_START_INDEX as u32;
392 } else {
393 (*window).lowLimit = ((*window).lowLimit).wrapping_sub(correction);
394 }
395 if (*window).dictLimit < correction.wrapping_add(ZSTD_WINDOW_START_INDEX as u32) {
396 (*window).dictLimit = ZSTD_WINDOW_START_INDEX as u32;
397 } else {
398 (*window).dictLimit = ((*window).dictLimit).wrapping_sub(correction);
399 }
400 (*window).nbOverflowCorrections = ((*window).nbOverflowCorrections).wrapping_add(1);
401 (*window).nbOverflowCorrections;
402 correction
403}
404#[inline]
405unsafe fn ZSTD_window_enforceMaxDist(
406 window: *mut ZSTD_window_t,
407 blockEnd: *const core::ffi::c_void,
408 maxDist: u32,
409 loadedDictEndPtr: *mut u32,
410 dictMatchStatePtr: *mut *const ZSTD_MatchState_t,
411) {
412 let blockEndIdx =
413 (blockEnd as *const u8).offset_from((*window).base) as core::ffi::c_long as u32;
414 let loadedDictEnd = if !loadedDictEndPtr.is_null() {
415 *loadedDictEndPtr
416 } else {
417 0
418 };
419 if blockEndIdx > maxDist.wrapping_add(loadedDictEnd) {
420 let newLowLimit = blockEndIdx.wrapping_sub(maxDist);
421 if (*window).lowLimit < newLowLimit {
422 (*window).lowLimit = newLowLimit;
423 }
424 if (*window).dictLimit < (*window).lowLimit {
425 (*window).dictLimit = (*window).lowLimit;
426 }
427 if !loadedDictEndPtr.is_null() {
428 *loadedDictEndPtr = 0;
429 }
430 if !dictMatchStatePtr.is_null() {
431 *dictMatchStatePtr = core::ptr::null();
432 }
433 }
434}
435#[inline]
436unsafe fn ZSTD_cwksp_alloc_size(size: size_t) -> size_t {
437 if size == 0 {
438 return 0;
439 }
440 size
441}
442#[inline]
443unsafe fn ZSTD_countTrailingZeros32(val: u32) -> core::ffi::c_uint {
444 val.trailing_zeros() as i32 as core::ffi::c_uint
445}
446#[inline]
447unsafe fn ZSTD_countLeadingZeros32(val: u32) -> core::ffi::c_uint {
448 val.leading_zeros() as i32 as core::ffi::c_uint
449}
450#[inline]
451unsafe fn ZSTD_countTrailingZeros64(val: u64) -> core::ffi::c_uint {
452 (val as core::ffi::c_ulonglong).trailing_zeros() as i32 as core::ffi::c_uint
453}
454#[inline]
455unsafe fn ZSTD_countLeadingZeros64(val: u64) -> core::ffi::c_uint {
456 (val as core::ffi::c_ulonglong).leading_zeros() as i32 as core::ffi::c_uint
457}
458#[inline]
459unsafe fn ZSTD_NbCommonBytes(val: size_t) -> core::ffi::c_uint {
460 if MEM_isLittleEndian() != 0 {
461 if MEM_64bits() != 0 {
462 ZSTD_countTrailingZeros64(val as u64) >> 3
463 } else {
464 ZSTD_countTrailingZeros32(val as u32) >> 3
465 }
466 } else if MEM_64bits() != 0 {
467 ZSTD_countLeadingZeros64(val as u64) >> 3
468 } else {
469 ZSTD_countLeadingZeros32(val as u32) >> 3
470 }
471}
472static ZSTD_ldm_gearTab: [u64; 256] = [
473 0xf5b8f72c5f77775c,
474 0x84935f266b7ac412,
475 0xb647ada9ca730ccc,
476 0xb065bb4b114fb1de,
477 0x34584e7e8c3a9fd0,
478 0x4e97e17c6ae26b05,
479 0x3a03d743bc99a604,
480 0xcecd042422c4044f,
481 0x76de76c58524259e,
482 0x9c8528f65badeaca,
483 0x86563706e2097529,
484 0x2902475fa375d889,
485 0xafb32a9739a5ebe6,
486 0xce2714da3883e639,
487 0x21eaf821722e69e,
488 0x37b628620b628,
489 0x49a8d455d88caf5,
490 0x8556d711e6958140,
491 0x4f7ae74fc605c1f,
492 0x829f0c3468bd3a20,
493 0x4ffdc885c625179e,
494 0x8473de048a3daf1b,
495 0x51008822b05646b2,
496 0x69d75d12b2d1cc5f,
497 0x8c9d4a19159154bc,
498 0xc3cc10f4abbd4003,
499 0xd06ddc1cecb97391,
500 0xbe48e6e7ed80302e,
501 0x3481db31cee03547,
502 0xacc3f67cdaa1d210,
503 0x65cb771d8c7f96cc,
504 0x8eb27177055723dd,
505 0xc789950d44cd94be,
506 0x934feadc3700b12b,
507 0x5e485f11edbdf182,
508 0x1e2e2a46fd64767a,
509 0x2969ca71d82efa7c,
510 0x9d46e9935ebbba2e,
511 0xe056b67e05e6822b,
512 0x94d73f55739d03a0,
513 0xcd7010bdb69b5a03,
514 0x455ef9fcd79b82f4,
515 0x869cb54a8749c161,
516 0x38d1a4fa6185d225,
517 0xb475166f94bbe9bb,
518 0xa4143548720959f1,
519 0x7aed4780ba6b26ba,
520 0xd0ce264439e02312,
521 0x84366d746078d508,
522 0xa8ce973c72ed17be,
523 0x21c323a29a430b01,
524 0x9962d617e3af80ee,
525 0xab0ce91d9c8cf75b,
526 0x530e8ee6d19a4dbc,
527 0x2ef68c0cf53f5d72,
528 0xc03a681640a85506,
529 0x496e4e9f9c310967,
530 0x78580472b59b14a0,
531 0x273824c23b388577,
532 0x66bf923ad45cb553,
533 0x47ae1a5a2492ba86,
534 0x35e304569e229659,
535 0x4765182a46870b6f,
536 0x6cbab625e9099412,
537 0xddac9a2e598522c1,
538 0x7172086e666624f2,
539 0xdf5003ca503b7837,
540 0x88c0c1db78563d09,
541 0x58d51865acfc289d,
542 0x177671aec65224f1,
543 0xfb79d8a241e967d7,
544 0x2be1e101cad9a49a,
545 0x6625682f6e29186b,
546 0x399553457ac06e50,
547 0x35dffb4c23abb74,
548 0x429db2591f54aade,
549 0xc52802a8037d1009,
550 0x6acb27381f0b25f3,
551 0xf45e2551ee4f823b,
552 0x8b0ea2d99580c2f7,
553 0x3bed519cbcb4e1e1,
554 0xff452823dbb010a,
555 0x9d42ed614f3dd267,
556 0x5b9313c06257c57b,
557 0xa114b8008b5e1442,
558 0xc1fe311c11c13d4b,
559 0x66e8763ea34c5568,
560 0x8b982af1c262f05d,
561 0xee8876faaa75fbb7,
562 0x8a62a4d0d172bb2a,
563 0xc13d94a3b7449a97,
564 0x6dbbba9dc15d037c,
565 0xc786101f1d92e0f1,
566 0xd78681a907a0b79b,
567 0xf61aaf2962c9abb9,
568 0x2cfd16fcd3cb7ad9,
569 0x868c5b6744624d21,
570 0x25e650899c74ddd7,
571 0xba042af4a7c37463,
572 0x4eb1a539465a3eca,
573 0xbe09dbf03b05d5ca,
574 0x774e5a362b5472ba,
575 0x47a1221229d183cd,
576 0x504b0ca18ef5a2df,
577 0xdffbdfbde2456eb9,
578 0x46cd2b2fbee34634,
579 0xf2aef8fe819d98c3,
580 0x357f5276d4599d61,
581 0x24a5483879c453e3,
582 0x88026889192b4b9,
583 0x28da96671782dbec,
584 0x4ef37c40588e9aaa,
585 0x8837b90651bc9fb3,
586 0xc164f741d3f0e5d6,
587 0xbc135a0a704b70ba,
588 0x69cd868f7622ada,
589 0xbc37ba89e0b9c0ab,
590 0x47c14a01323552f6,
591 0x4f00794bacee98bb,
592 0x7107de7d637a69d5,
593 0x88af793bb6f2255e,
594 0xf3c6466b8799b598,
595 0xc288c616aa7f3b59,
596 0x81ca63cf42fca3fd,
597 0x88d85ace36a2674b,
598 0xd056bd3792389e7,
599 0xe55c396c4e9dd32d,
600 0xbefb504571e6c0a6,
601 0x96ab32115e91e8cc,
602 0xbf8acb18de8f38d1,
603 0x66dae58801672606,
604 0x833b6017872317fb,
605 0xb87c16f2d1c92864,
606 0xdb766a74e58b669c,
607 0x89659f85c61417be,
608 0xc8daad856011ea0c,
609 0x76a4b565b6fe7eae,
610 0xa469d085f6237312,
611 0xaaf0365683a3e96c,
612 0x4dbb746f8424f7b8,
613 0x638755af4e4acc1,
614 0x3d7807f5bde64486,
615 0x17be6d8f5bbb7639,
616 0x903f0cd44dc35dc,
617 0x67b672eafdf1196c,
618 0xa676ff93ed4c82f1,
619 0x521d1004c5053d9d,
620 0x37ba9ad09ccc9202,
621 0x84e54d297aacfb51,
622 0xa0b4b776a143445,
623 0x820d471e20b348e,
624 0x1874383cb83d46dc,
625 0x97edeec7a1efe11c,
626 0xb330e50b1bdc42aa,
627 0x1dd91955ce70e032,
628 0xa514cdb88f2939d5,
629 0x2791233fd90db9d3,
630 0x7b670a4cc50f7a9b,
631 0x77c07d2a05c6dfa5,
632 0xe3778b6646d0a6fa,
633 0xb39c8eda47b56749,
634 0x933ed448addbef28,
635 0xaf846af6ab7d0bf4,
636 0xe5af208eb666e49,
637 0x5e6622f73534cd6a,
638 0x297daeca42ef5b6e,
639 0x862daef3d35539a6,
640 0xe68722498f8e1ea9,
641 0x981c53093dc0d572,
642 0xfa09b0bfbf86fbf5,
643 0x30b1e96166219f15,
644 0x70e7d466bdc4fb83,
645 0x5a66736e35f2a8e9,
646 0xcddb59d2b7c1baef,
647 0xd6c7d247d26d8996,
648 0xea4e39eac8de1ba3,
649 0x539c8bb19fa3aff2,
650 0x9f90e4c5fd508d8,
651 0xa34e5956fbaf3385,
652 0x2e2f8e151d3ef375,
653 0x173691e9b83faec1,
654 0xb85a8d56bf016379,
655 0x8382381267408ae3,
656 0xb90f901bbdc0096d,
657 0x7c6ad32933bcec65,
658 0x76bb5e2f2c8ad595,
659 0x390f851a6cf46d28,
660 0xc3e6064da1c2da72,
661 0xc52a0c101cfa5389,
662 0xd78eaf84a3fbc530,
663 0x3781b9e2288b997e,
664 0x73c2f6dea83d05c4,
665 0x4228e364c5b5ed7,
666 0x9d7a3edf0da43911,
667 0x8edcfeda24686756,
668 0x5e7667a7b7a9b3a1,
669 0x4c4f389fa143791d,
670 0xb08bc1023da7cddc,
671 0x7ab4be3ae529b1cc,
672 0x754e6132dbe74ff9,
673 0x71635442a839df45,
674 0x2f6fb1643fbe52de,
675 0x961e0a42cf7a8177,
676 0xf3b45d83d89ef2ea,
677 0xee3de4cf4a6e3e9b,
678 0xcd6848542c3295e7,
679 0xe4cee1664c78662f,
680 0x9947548b474c68c4,
681 0x25d73777a5ed8b0b,
682 0xc915b1d636b7fc,
683 0x21c2ba75d9b0d2da,
684 0x5f6b5dcf608a64a1,
685 0xdcf333255ff9570c,
686 0x633b922418ced4ee,
687 0xc136dde0b004b34a,
688 0x58cc83b05d4b2f5a,
689 0x5eb424dda28e42d2,
690 0x62df47369739cd98,
691 0xb4e0b42485e4ce17,
692 0x16e1f0c1f9a8d1e7,
693 0x8ec3916707560ebf,
694 0x62ba6e2df2cc9db3,
695 0xcbf9f4ff77d83a16,
696 0x78d9d7d07d2bbcc4,
697 0xef554ce1e02c41f4,
698 0x8d7581127eccf94d,
699 0xa9b53336cb3c8a05,
700 0x38c42c0bf45c4f91,
701 0x640893cdf4488863,
702 0x80ec34bc575ea568,
703 0x39f324f5b48eaa40,
704 0xe9d9ed1f8eff527f,
705 0x9224fc058cc5a214,
706 0xbaba00b04cfe7741,
707 0x309a9f120fcf52af,
708 0xa558f3ec65626212,
709 0x424bec8b7adabe2f,
710 0x41622513a6aea433,
711 0xb88da2d5324ca798,
712 0xd287733b245528a4,
713 0x9a44697e6d68aec3,
714 0x7b1093be2f49bb28,
715 0x50bbec632e3d8aad,
716 0x6cd90723e1ea8283,
717 0x897b9e7431b02bf3,
718 0x219efdcb338a7047,
719 0x3b0311f0a27c0656,
720 0xdb17bf91c0db96e7,
721 0x8cd4fd6b4e85a5b2,
722 0xfab071054ba6409d,
723 0x40d6fe831fa9dfd9,
724 0xaf358debad7d791e,
725 0xeb8d0e25a65e3e58,
726 0xbbcbd3df14e08580,
727 0xcf751f27ecdab2b,
728 0x2b4da14f2613d8f4,
729];
730pub const LDM_MIN_MATCH_LENGTH: core::ffi::c_int = 64;
731unsafe fn ZSTD_ldm_gear_init(state: *mut ldmRollingHashState_t, params: *const ldmParams_t) {
732 let maxBitsInMask = if (*params).minMatchLength < 64 {
733 (*params).minMatchLength
734 } else {
735 64
736 };
737 let hashRateLog = (*params).hashRateLog;
738 (*state).rolling = !0u32 as u64;
739 if hashRateLog > 0 as core::ffi::c_uint && hashRateLog <= maxBitsInMask {
740 (*state).stopMask =
741 (1u64 << hashRateLog).wrapping_sub(1) << maxBitsInMask.wrapping_sub(hashRateLog);
742 } else {
743 (*state).stopMask = (1u64 << hashRateLog).wrapping_sub(1);
744 };
745}
746unsafe fn ZSTD_ldm_gear_reset(
747 state: *mut ldmRollingHashState_t,
748 data: *const u8,
749 minMatchLength: size_t,
750) {
751 let mut hash = (*state).rolling;
752 let mut n = 0 as size_t;
753 while n.wrapping_add(3) < minMatchLength {
754 hash = (hash << 1).wrapping_add(
755 *ZSTD_ldm_gearTab
756 .as_ptr()
757 .offset((*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize),
758 );
759 n = n.wrapping_add(1);
760 hash = (hash << 1).wrapping_add(
761 *ZSTD_ldm_gearTab
762 .as_ptr()
763 .offset((*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize),
764 );
765 n = n.wrapping_add(1);
766 hash = (hash << 1).wrapping_add(
767 *ZSTD_ldm_gearTab
768 .as_ptr()
769 .offset((*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize),
770 );
771 n = n.wrapping_add(1);
772 hash = (hash << 1).wrapping_add(
773 *ZSTD_ldm_gearTab
774 .as_ptr()
775 .offset((*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize),
776 );
777 n = n.wrapping_add(1);
778 }
779 while n < minMatchLength {
780 hash = (hash << 1).wrapping_add(
781 *ZSTD_ldm_gearTab
782 .as_ptr()
783 .offset((*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize),
784 );
785 n = n.wrapping_add(1);
786 }
787}
788unsafe fn ZSTD_ldm_gear_feed(
789 state: *mut ldmRollingHashState_t,
790 data: *const u8,
791 size: size_t,
792 splits: *mut size_t,
793 numSplits: *mut core::ffi::c_uint,
794) -> size_t {
795 let mut current_block: u64;
796 let mut n: size_t = 0;
797 let mut hash: u64 = 0;
798 let mut mask: u64 = 0;
799 hash = (*state).rolling;
800 mask = (*state).stopMask;
801 n = 0;
802 loop {
803 if n.wrapping_add(3) >= size {
804 current_block = 5689316957504528238;
805 break;
806 }
807 hash = (hash << 1).wrapping_add(
808 *ZSTD_ldm_gearTab
809 .as_ptr()
810 .offset((*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize),
811 );
812 n = n.wrapping_add(1);
813 if (hash & mask == 0) as core::ffi::c_int as core::ffi::c_long != 0 {
814 *splits.offset(*numSplits as isize) = n;
815 *numSplits = (*numSplits).wrapping_add(1);
816 if *numSplits == LDM_BATCH_SIZE as core::ffi::c_uint {
817 current_block = 12351618399163395313;
818 break;
819 }
820 }
821 hash = (hash << 1).wrapping_add(
822 *ZSTD_ldm_gearTab
823 .as_ptr()
824 .offset((*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize),
825 );
826 n = n.wrapping_add(1);
827 if (hash & mask == 0) as core::ffi::c_int as core::ffi::c_long != 0 {
828 *splits.offset(*numSplits as isize) = n;
829 *numSplits = (*numSplits).wrapping_add(1);
830 if *numSplits == LDM_BATCH_SIZE as core::ffi::c_uint {
831 current_block = 12351618399163395313;
832 break;
833 }
834 }
835 hash = (hash << 1).wrapping_add(
836 *ZSTD_ldm_gearTab
837 .as_ptr()
838 .offset((*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize),
839 );
840 n = n.wrapping_add(1);
841 if (hash & mask == 0) as core::ffi::c_int as core::ffi::c_long != 0 {
842 *splits.offset(*numSplits as isize) = n;
843 *numSplits = (*numSplits).wrapping_add(1);
844 if *numSplits == LDM_BATCH_SIZE as core::ffi::c_uint {
845 current_block = 12351618399163395313;
846 break;
847 }
848 }
849 hash = (hash << 1).wrapping_add(
850 *ZSTD_ldm_gearTab
851 .as_ptr()
852 .offset((*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize),
853 );
854 n = n.wrapping_add(1);
855 if (hash & mask == 0) as core::ffi::c_int as core::ffi::c_long == 0 {
856 continue;
857 }
858 *splits.offset(*numSplits as isize) = n;
859 *numSplits = (*numSplits).wrapping_add(1);
860 if *numSplits == LDM_BATCH_SIZE as core::ffi::c_uint {
861 current_block = 12351618399163395313;
862 break;
863 }
864 }
865 loop {
866 match current_block {
867 12351618399163395313 => {
868 (*state).rolling = hash;
869 break;
870 }
871 _ => {
872 if n >= size {
873 current_block = 12351618399163395313;
874 continue;
875 }
876 hash = (hash << 1).wrapping_add(*ZSTD_ldm_gearTab.as_ptr().offset(
877 (*data.add(n) as core::ffi::c_int & 0xff as core::ffi::c_int) as isize,
878 ));
879 n = n.wrapping_add(1);
880 if (hash & mask == 0) as core::ffi::c_int as core::ffi::c_long == 0 {
881 current_block = 5689316957504528238;
882 continue;
883 }
884 *splits.offset(*numSplits as isize) = n;
885 *numSplits = (*numSplits).wrapping_add(1);
886 if *numSplits == LDM_BATCH_SIZE as core::ffi::c_uint {
887 current_block = 12351618399163395313;
888 } else {
889 current_block = 5689316957504528238;
890 }
891 }
892 }
893 }
894 n
895}
896pub unsafe fn ZSTD_ldm_adjustParameters(
897 params: *mut ldmParams_t,
898 cParams: *const ZSTD_compressionParameters,
899) {
900 (*params).windowLog = (*cParams).windowLog;
901 if (*params).hashRateLog == 0 {
902 if (*params).hashLog > 0 {
903 if (*params).windowLog > (*params).hashLog {
904 (*params).hashRateLog = ((*params).windowLog).wrapping_sub((*params).hashLog);
905 }
906 } else {
907 (*params).hashRateLog = (7 as core::ffi::c_uint)
908 .wrapping_sub(((*cParams).strategy as core::ffi::c_uint).wrapping_div(3));
909 }
910 }
911 if (*params).hashLog == 0 {
912 (*params).hashLog = if 6
913 > (if ((*params).windowLog).wrapping_sub((*params).hashRateLog)
914 < (if (if ::core::mem::size_of::<size_t>() as core::ffi::c_ulong == 4 {
915 30
916 } else {
917 31
918 }) < 30
919 {
920 if ::core::mem::size_of::<size_t>() as core::ffi::c_ulong == 4 {
921 30
922 } else {
923 31
924 }
925 } else {
926 30
927 }) as u32
928 {
929 ((*params).windowLog).wrapping_sub((*params).hashRateLog)
930 } else {
931 (if (if ::core::mem::size_of::<size_t>() as core::ffi::c_ulong == 4 {
932 30
933 } else {
934 31
935 }) < 30
936 {
937 if ::core::mem::size_of::<size_t>() as core::ffi::c_ulong == 4 {
938 30
939 } else {
940 31
941 }
942 } else {
943 30
944 }) as u32
945 }) {
946 6
947 } else if ((*params).windowLog).wrapping_sub((*params).hashRateLog)
948 < (if (if ::core::mem::size_of::<size_t>() as core::ffi::c_ulong == 4 {
949 30
950 } else {
951 31
952 }) < 30
953 {
954 if ::core::mem::size_of::<size_t>() as core::ffi::c_ulong == 4 {
955 30
956 } else {
957 31
958 }
959 } else {
960 30
961 }) as u32
962 {
963 ((*params).windowLog).wrapping_sub((*params).hashRateLog)
964 } else {
965 (if (if ::core::mem::size_of::<size_t>() as core::ffi::c_ulong == 4 {
966 30
967 } else {
968 31
969 }) < 30
970 {
971 if ::core::mem::size_of::<size_t>() as core::ffi::c_ulong == 4 {
972 30
973 } else {
974 31
975 }
976 } else {
977 30
978 }) as u32
979 };
980 }
981 if (*params).minMatchLength == 0 {
982 (*params).minMatchLength = LDM_MIN_MATCH_LENGTH as u32;
983 if (*cParams).strategy as core::ffi::c_uint
984 >= ZSTD_btultra as core::ffi::c_int as core::ffi::c_uint
985 {
986 (*params).minMatchLength /= 2;
987 }
988 }
989 if (*params).bucketSizeLog == 0 {
990 (*params).bucketSizeLog = if 4
991 > (if (*cParams).strategy < 8 {
992 (*cParams).strategy
993 } else {
994 8
995 }) {
996 4
997 } else if (*cParams).strategy < 8 {
998 (*cParams).strategy
999 } else {
1000 8
1001 };
1002 }
1003 (*params).bucketSizeLog = if (*params).bucketSizeLog < (*params).hashLog {
1004 (*params).bucketSizeLog
1005 } else {
1006 (*params).hashLog
1007 };
1008}
1009pub unsafe fn ZSTD_ldm_getTableSize(params: ldmParams_t) -> size_t {
1010 let ldmHSize = (1 as size_t) << params.hashLog;
1011 let ldmBucketSizeLog = (if params.bucketSizeLog < params.hashLog {
1012 params.bucketSizeLog
1013 } else {
1014 params.hashLog
1015 }) as size_t;
1016 let ldmBucketSize = (1) << (params.hashLog as size_t).wrapping_sub(ldmBucketSizeLog);
1017 let totalSize = (ZSTD_cwksp_alloc_size(ldmBucketSize)).wrapping_add(ZSTD_cwksp_alloc_size(
1018 ldmHSize.wrapping_mul(::core::mem::size_of::<ldmEntry_t>()),
1019 ));
1020 if params.enableLdm as core::ffi::c_uint
1021 == ZSTD_ps_enable as core::ffi::c_int as core::ffi::c_uint
1022 {
1023 totalSize
1024 } else {
1025 0
1026 }
1027}
1028pub unsafe fn ZSTD_ldm_getMaxNbSeq(params: ldmParams_t, maxChunkSize: size_t) -> size_t {
1029 if params.enableLdm as core::ffi::c_uint
1030 == ZSTD_ps_enable as core::ffi::c_int as core::ffi::c_uint
1031 {
1032 maxChunkSize / params.minMatchLength as size_t
1033 } else {
1034 0
1035 }
1036}
1037unsafe fn ZSTD_ldm_getBucket(
1038 ldmState: *const ldmState_t,
1039 hash: size_t,
1040 bucketSizeLog: u32,
1041) -> *mut ldmEntry_t {
1042 ((*ldmState).hashTable).add(hash << bucketSizeLog)
1043}
1044unsafe fn ZSTD_ldm_insertEntry(
1045 ldmState: *mut ldmState_t,
1046 hash: size_t,
1047 entry: ldmEntry_t,
1048 bucketSizeLog: u32,
1049) {
1050 let pOffset = ((*ldmState).bucketOffsets).add(hash);
1051 let offset = *pOffset as core::ffi::c_uint;
1052 *(ZSTD_ldm_getBucket(ldmState, hash, bucketSizeLog)).offset(offset as isize) = entry;
1053 *pOffset = (offset.wrapping_add(1)
1054 & ((1 as core::ffi::c_uint) << bucketSizeLog).wrapping_sub(1)) as u8;
1055}
1056unsafe fn ZSTD_ldm_countBackwardsMatch(
1057 mut pIn: *const u8,
1058 pAnchor: *const u8,
1059 mut pMatch: *const u8,
1060 pMatchBase: *const u8,
1061) -> size_t {
1062 let mut matchLength = 0 as size_t;
1063 while pIn > pAnchor
1064 && pMatch > pMatchBase
1065 && *pIn.offset(-1_isize) as core::ffi::c_int == *pMatch.offset(-1_isize) as core::ffi::c_int
1066 {
1067 pIn = pIn.offset(-1);
1068 pMatch = pMatch.offset(-1);
1069 matchLength = matchLength.wrapping_add(1);
1070 }
1071 matchLength
1072}
1073unsafe fn ZSTD_ldm_countBackwardsMatch_2segments(
1074 pIn: *const u8,
1075 pAnchor: *const u8,
1076 pMatch: *const u8,
1077 pMatchBase: *const u8,
1078 pExtDictStart: *const u8,
1079 pExtDictEnd: *const u8,
1080) -> size_t {
1081 let mut matchLength = ZSTD_ldm_countBackwardsMatch(pIn, pAnchor, pMatch, pMatchBase);
1082 if pMatch.offset(-(matchLength as isize)) != pMatchBase || pMatchBase == pExtDictStart {
1083 return matchLength;
1084 }
1085 matchLength = matchLength.wrapping_add(ZSTD_ldm_countBackwardsMatch(
1086 pIn.offset(-(matchLength as isize)),
1087 pAnchor,
1088 pExtDictEnd,
1089 pExtDictStart,
1090 ));
1091 matchLength
1092}
1093unsafe fn ZSTD_ldm_fillFastTables(
1094 ms: *mut ZSTD_MatchState_t,
1095 end: *const core::ffi::c_void,
1096) -> size_t {
1097 let iend = end as *const u8;
1098 match (*ms).cParams.strategy as core::ffi::c_uint {
1099 1 => {
1100 ZSTD_fillHashTable(
1101 ms,
1102 iend as *const core::ffi::c_void,
1103 ZSTD_dtlm_fast,
1104 ZSTD_tfp_forCCtx,
1105 );
1106 }
1107 2 => {
1108 ZSTD_fillDoubleHashTable(
1109 ms,
1110 iend as *const core::ffi::c_void,
1111 ZSTD_dtlm_fast,
1112 ZSTD_tfp_forCCtx,
1113 );
1114 }
1115 3 | 4 | 5 | 6 | 7 | 8 | 9 | _ => {}
1116 }
1117 0
1118}
1119pub unsafe fn ZSTD_ldm_fillHashTable(
1120 ldmState: *mut ldmState_t,
1121 mut ip: *const u8,
1122 iend: *const u8,
1123 params: *const ldmParams_t,
1124) {
1125 let minMatchLength = (*params).minMatchLength;
1126 let bucketSizeLog = (*params).bucketSizeLog;
1127 let hBits = ((*params).hashLog).wrapping_sub(bucketSizeLog);
1128 let base = (*ldmState).window.base;
1129 let istart = ip;
1130 let mut hashState = ldmRollingHashState_t {
1131 rolling: 0,
1132 stopMask: 0,
1133 };
1134 let splits = ((*ldmState).splitIndices).as_mut_ptr();
1135 let mut numSplits: core::ffi::c_uint = 0;
1136 ZSTD_ldm_gear_init(&mut hashState, params);
1137 while ip < iend {
1138 let mut hashed: size_t = 0;
1139 let mut n: core::ffi::c_uint = 0;
1140 numSplits = 0;
1141 hashed = ZSTD_ldm_gear_feed(
1142 &mut hashState,
1143 ip,
1144 iend.offset_from(ip) as size_t,
1145 splits,
1146 &mut numSplits,
1147 );
1148 n = 0;
1149 while n < numSplits {
1150 if ip.add(*splits.offset(n as isize)) >= istart.offset(minMatchLength as isize) {
1151 let split = ip
1152 .add(*splits.offset(n as isize))
1153 .offset(-(minMatchLength as isize));
1154 let xxhash = ZSTD_XXH64(
1155 split as *const core::ffi::c_void,
1156 minMatchLength as usize,
1157 0,
1158 );
1159 let hash = (xxhash & (1u32 << hBits).wrapping_sub(1) as u64) as u32;
1160 let mut entry = ldmEntry_t {
1161 offset: 0,
1162 checksum: 0,
1163 };
1164 entry.offset = split.offset_from(base) as core::ffi::c_long as u32;
1165 entry.checksum = (xxhash >> 32) as u32;
1166 ZSTD_ldm_insertEntry(ldmState, hash as size_t, entry, (*params).bucketSizeLog);
1167 }
1168 n = n.wrapping_add(1);
1169 }
1170 ip = ip.add(hashed);
1171 }
1172}
1173unsafe fn ZSTD_ldm_limitTableUpdate(ms: *mut ZSTD_MatchState_t, anchor: *const u8) {
1174 let curr = anchor.offset_from((*ms).window.base) as core::ffi::c_long as u32;
1175 if curr > ((*ms).nextToUpdate).wrapping_add(1024) {
1176 (*ms).nextToUpdate = curr.wrapping_sub(
1177 if (512) < curr.wrapping_sub((*ms).nextToUpdate).wrapping_sub(1024) {
1178 512
1179 } else {
1180 curr.wrapping_sub((*ms).nextToUpdate).wrapping_sub(1024)
1181 },
1182 );
1183 }
1184}
1185unsafe fn ZSTD_ldm_generateSequences_internal(
1186 ldmState: *mut ldmState_t,
1187 rawSeqStore: *mut RawSeqStore_t,
1188 params: *const ldmParams_t,
1189 src: *const core::ffi::c_void,
1190 srcSize: size_t,
1191) -> size_t {
1192 let extDict = ZSTD_window_hasExtDict((*ldmState).window) as core::ffi::c_int;
1193 let minMatchLength = (*params).minMatchLength;
1194 let entsPerBucket = (1) << (*params).bucketSizeLog;
1195 let hBits = ((*params).hashLog).wrapping_sub((*params).bucketSizeLog);
1196 let dictLimit = (*ldmState).window.dictLimit;
1197 let lowestIndex = if extDict != 0 {
1198 (*ldmState).window.lowLimit
1199 } else {
1200 dictLimit
1201 };
1202 let base = (*ldmState).window.base;
1203 let dictBase = if extDict != 0 {
1204 (*ldmState).window.dictBase
1205 } else {
1206 core::ptr::null()
1207 };
1208 let dictStart = if extDict != 0 {
1209 dictBase.offset(lowestIndex as isize)
1210 } else {
1211 core::ptr::null()
1212 };
1213 let dictEnd = if extDict != 0 {
1214 dictBase.offset(dictLimit as isize)
1215 } else {
1216 core::ptr::null()
1217 };
1218 let lowPrefixPtr = base.offset(dictLimit as isize);
1219 let istart = src as *const u8;
1220 let iend = istart.add(srcSize);
1221 let ilimit = iend.offset(-(HASH_READ_SIZE as isize));
1222 let mut anchor = istart;
1223 let mut ip = istart;
1224 let mut hashState = ldmRollingHashState_t {
1225 rolling: 0,
1226 stopMask: 0,
1227 };
1228 let splits = ((*ldmState).splitIndices).as_mut_ptr();
1229 let candidates = ((*ldmState).matchCandidates).as_mut_ptr();
1230 let mut numSplits: core::ffi::c_uint = 0;
1231 if srcSize < minMatchLength as size_t {
1232 return iend.offset_from(anchor) as size_t;
1233 }
1234 ZSTD_ldm_gear_init(&mut hashState, params);
1235 ZSTD_ldm_gear_reset(&mut hashState, ip, minMatchLength as size_t);
1236 ip = ip.offset(minMatchLength as isize);
1237 while ip < ilimit {
1238 let mut hashed: size_t = 0;
1239 let mut n: core::ffi::c_uint = 0;
1240 numSplits = 0;
1241 hashed = ZSTD_ldm_gear_feed(
1242 &mut hashState,
1243 ip,
1244 ilimit.offset_from(ip) as size_t,
1245 splits,
1246 &mut numSplits,
1247 );
1248 n = 0;
1249 while n < numSplits {
1250 let split = ip
1251 .add(*splits.offset(n as isize))
1252 .offset(-(minMatchLength as isize));
1253 let xxhash = ZSTD_XXH64(
1254 split as *const core::ffi::c_void,
1255 minMatchLength as usize,
1256 0,
1257 );
1258 let hash = (xxhash & (1u32 << hBits).wrapping_sub(1) as u64) as u32;
1259 let fresh2 = &mut (*candidates.offset(n as isize)).split;
1260 *fresh2 = split;
1261 (*candidates.offset(n as isize)).hash = hash;
1262 (*candidates.offset(n as isize)).checksum = (xxhash >> 32) as u32;
1263 let fresh3 = &mut (*candidates.offset(n as isize)).bucket;
1264 *fresh3 = ZSTD_ldm_getBucket(ldmState, hash as size_t, (*params).bucketSizeLog);
1265 n = n.wrapping_add(1);
1266 }
1267 n = 0;
1268 while n < numSplits {
1269 let mut forwardMatchLength = 0;
1270 let mut backwardMatchLength = 0;
1271 let mut bestMatchLength = 0;
1272 let mut mLength: size_t = 0;
1273 let mut offset: u32 = 0;
1274 let split_0 = (*candidates.offset(n as isize)).split;
1275 let checksum = (*candidates.offset(n as isize)).checksum;
1276 let hash_0 = (*candidates.offset(n as isize)).hash;
1277 let bucket = (*candidates.offset(n as isize)).bucket;
1278 let mut cur = core::ptr::null::<ldmEntry_t>();
1279 let mut bestEntry = core::ptr::null();
1280 let mut newEntry = ldmEntry_t {
1281 offset: 0,
1282 checksum: 0,
1283 };
1284 newEntry.offset = split_0.offset_from(base) as core::ffi::c_long as u32;
1285 newEntry.checksum = checksum;
1286 if split_0 < anchor {
1287 ZSTD_ldm_insertEntry(
1288 ldmState,
1289 hash_0 as size_t,
1290 newEntry,
1291 (*params).bucketSizeLog,
1292 );
1293 } else {
1294 let mut current_block_30: u64;
1295 cur = bucket;
1296 while cur < bucket.offset(entsPerBucket as isize) as *const ldmEntry_t {
1297 let mut curForwardMatchLength: size_t = 0;
1298 let mut curBackwardMatchLength: size_t = 0;
1299 let mut curTotalMatchLength: size_t = 0;
1300 if !((*cur).checksum != checksum || (*cur).offset <= lowestIndex) {
1301 if extDict != 0 {
1302 let curMatchBase = if (*cur).offset < dictLimit {
1303 dictBase
1304 } else {
1305 base
1306 };
1307 let pMatch = curMatchBase.offset((*cur).offset as isize);
1308 let matchEnd = if (*cur).offset < dictLimit {
1309 dictEnd
1310 } else {
1311 iend
1312 };
1313 let lowMatchPtr = if (*cur).offset < dictLimit {
1314 dictStart
1315 } else {
1316 lowPrefixPtr
1317 };
1318 curForwardMatchLength =
1319 ZSTD_count_2segments(split_0, pMatch, iend, matchEnd, lowPrefixPtr);
1320 if curForwardMatchLength < minMatchLength as size_t {
1321 current_block_30 = 17788412896529399552;
1322 } else {
1323 curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch_2segments(
1324 split_0,
1325 anchor,
1326 pMatch,
1327 lowMatchPtr,
1328 dictStart,
1329 dictEnd,
1330 );
1331 current_block_30 = 15512526488502093901;
1332 }
1333 } else {
1334 let pMatch_0 = base.offset((*cur).offset as isize);
1335 curForwardMatchLength = ZSTD_count(split_0, pMatch_0, iend);
1336 if curForwardMatchLength < minMatchLength as size_t {
1337 current_block_30 = 17788412896529399552;
1338 } else {
1339 curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch(
1340 split_0,
1341 anchor,
1342 pMatch_0,
1343 lowPrefixPtr,
1344 );
1345 current_block_30 = 15512526488502093901;
1346 }
1347 }
1348 match current_block_30 {
1349 17788412896529399552 => {}
1350 _ => {
1351 curTotalMatchLength =
1352 curForwardMatchLength.wrapping_add(curBackwardMatchLength);
1353 if curTotalMatchLength > bestMatchLength {
1354 bestMatchLength = curTotalMatchLength;
1355 forwardMatchLength = curForwardMatchLength;
1356 backwardMatchLength = curBackwardMatchLength;
1357 bestEntry = cur;
1358 }
1359 }
1360 }
1361 }
1362 cur = cur.offset(1);
1363 }
1364 if bestEntry.is_null() {
1365 ZSTD_ldm_insertEntry(
1366 ldmState,
1367 hash_0 as size_t,
1368 newEntry,
1369 (*params).bucketSizeLog,
1370 );
1371 } else {
1372 offset = (split_0.offset_from(base) as core::ffi::c_long as u32)
1373 .wrapping_sub((*bestEntry).offset);
1374 mLength = forwardMatchLength.wrapping_add(backwardMatchLength);
1375 let seq = ((*rawSeqStore).seq).add((*rawSeqStore).size);
1376 if (*rawSeqStore).size == (*rawSeqStore).capacity {
1377 return Error::dstSize_tooSmall.to_error_code();
1378 }
1379 (*seq).litLength = split_0
1380 .offset(-(backwardMatchLength as isize))
1381 .offset_from(anchor)
1382 as core::ffi::c_long as u32;
1383 (*seq).matchLength = mLength as u32;
1384 (*seq).offset = offset;
1385 (*rawSeqStore).size = ((*rawSeqStore).size).wrapping_add(1);
1386 (*rawSeqStore).size;
1387 ZSTD_ldm_insertEntry(
1388 ldmState,
1389 hash_0 as size_t,
1390 newEntry,
1391 (*params).bucketSizeLog,
1392 );
1393 anchor = split_0.add(forwardMatchLength);
1394 if anchor > ip.add(hashed) {
1395 ZSTD_ldm_gear_reset(
1396 &mut hashState,
1397 anchor.offset(-(minMatchLength as isize)),
1398 minMatchLength as size_t,
1399 );
1400 ip = anchor.offset(-(hashed as isize));
1401 break;
1402 }
1403 }
1404 }
1405 n = n.wrapping_add(1);
1406 }
1407 ip = ip.add(hashed);
1408 }
1409 iend.offset_from(anchor) as size_t
1410}
1411unsafe fn ZSTD_ldm_reduceTable(table: *mut ldmEntry_t, size: u32, reducerValue: u32) {
1412 let mut u: u32 = 0;
1413 u = 0;
1414 while u < size {
1415 if (*table.offset(u as isize)).offset < reducerValue {
1416 (*table.offset(u as isize)).offset = 0;
1417 } else {
1418 let fresh4 = &mut (*table.offset(u as isize)).offset;
1419 *fresh4 = (*fresh4).wrapping_sub(reducerValue);
1420 }
1421 u = u.wrapping_add(1);
1422 }
1423}
1424pub unsafe fn ZSTD_ldm_generateSequences(
1425 ldmState: *mut ldmState_t,
1426 sequences: *mut RawSeqStore_t,
1427 params: *const ldmParams_t,
1428 src: *const core::ffi::c_void,
1429 srcSize: size_t,
1430) -> size_t {
1431 let maxDist = (1) << (*params).windowLog;
1432 let istart = src as *const u8;
1433 let iend = istart.add(srcSize);
1434 let kMaxChunkSize = ((1) << 20) as size_t;
1435 let nbChunks = (srcSize / kMaxChunkSize)
1436 .wrapping_add(!srcSize.is_multiple_of(kMaxChunkSize) as core::ffi::c_int as size_t);
1437 let mut chunk: size_t = 0;
1438 let mut leftoverSize = 0;
1439 chunk = 0;
1440 while chunk < nbChunks && (*sequences).size < (*sequences).capacity {
1441 let chunkStart = istart.add(chunk * kMaxChunkSize);
1442 let remaining = iend.offset_from(chunkStart) as size_t;
1443 let chunkEnd = if remaining < kMaxChunkSize {
1444 iend
1445 } else {
1446 chunkStart.add(kMaxChunkSize)
1447 };
1448 let chunkSize = chunkEnd.offset_from(chunkStart) as size_t;
1449 let mut newLeftoverSize: size_t = 0;
1450 let prevSize = (*sequences).size;
1451 if ZSTD_window_needOverflowCorrection(
1452 (*ldmState).window,
1453 0,
1454 maxDist,
1455 (*ldmState).loadedDictEnd,
1456 chunkStart as *const core::ffi::c_void,
1457 chunkEnd as *const core::ffi::c_void,
1458 ) != 0
1459 {
1460 let ldmHSize = (1) << (*params).hashLog;
1461 let correction = ZSTD_window_correctOverflow(
1462 &mut (*ldmState).window,
1463 0,
1464 maxDist,
1465 chunkStart as *const core::ffi::c_void,
1466 );
1467 ZSTD_ldm_reduceTable((*ldmState).hashTable, ldmHSize, correction);
1468 (*ldmState).loadedDictEnd = 0;
1469 }
1470 ZSTD_window_enforceMaxDist(
1471 &mut (*ldmState).window,
1472 chunkEnd as *const core::ffi::c_void,
1473 maxDist,
1474 &mut (*ldmState).loadedDictEnd,
1475 core::ptr::null_mut(),
1476 );
1477 newLeftoverSize = ZSTD_ldm_generateSequences_internal(
1478 ldmState,
1479 sequences,
1480 params,
1481 chunkStart as *const core::ffi::c_void,
1482 chunkSize,
1483 );
1484 if ERR_isError(newLeftoverSize) {
1485 return newLeftoverSize;
1486 }
1487 if prevSize < (*sequences).size {
1488 let fresh5 = &mut (*((*sequences).seq).add(prevSize)).litLength;
1489 *fresh5 = (*fresh5).wrapping_add(leftoverSize as u32);
1490 leftoverSize = newLeftoverSize;
1491 } else {
1492 leftoverSize = leftoverSize.wrapping_add(chunkSize);
1493 }
1494 chunk = chunk.wrapping_add(1);
1495 }
1496 0
1497}
1498pub unsafe fn ZSTD_ldm_skipSequences(
1499 rawSeqStore: *mut RawSeqStore_t,
1500 mut srcSize: size_t,
1501 minMatch: u32,
1502) {
1503 while srcSize > 0 && (*rawSeqStore).pos < (*rawSeqStore).size {
1504 let seq = ((*rawSeqStore).seq).add((*rawSeqStore).pos);
1505 if srcSize <= (*seq).litLength as size_t {
1506 (*seq).litLength = ((*seq).litLength).wrapping_sub(srcSize as u32);
1507 return;
1508 }
1509 srcSize = srcSize.wrapping_sub((*seq).litLength as size_t);
1510 (*seq).litLength = 0;
1511 if srcSize < (*seq).matchLength as size_t {
1512 (*seq).matchLength = ((*seq).matchLength).wrapping_sub(srcSize as u32);
1513 if (*seq).matchLength < minMatch {
1514 if ((*rawSeqStore).pos).wrapping_add(1) < (*rawSeqStore).size {
1515 let fresh6 = &mut (*seq.offset(1)).litLength;
1516 *fresh6 = (*fresh6).wrapping_add((*seq.offset(0)).matchLength);
1517 }
1518 (*rawSeqStore).pos = ((*rawSeqStore).pos).wrapping_add(1);
1519 (*rawSeqStore).pos;
1520 }
1521 return;
1522 }
1523 srcSize = srcSize.wrapping_sub((*seq).matchLength as size_t);
1524 (*seq).matchLength = 0;
1525 (*rawSeqStore).pos = ((*rawSeqStore).pos).wrapping_add(1);
1526 (*rawSeqStore).pos;
1527 }
1528}
1529unsafe fn maybeSplitSequence(
1530 rawSeqStore: *mut RawSeqStore_t,
1531 remaining: u32,
1532 minMatch: u32,
1533) -> rawSeq {
1534 let mut sequence = *((*rawSeqStore).seq).add((*rawSeqStore).pos);
1535 if remaining >= (sequence.litLength).wrapping_add(sequence.matchLength) {
1536 (*rawSeqStore).pos = ((*rawSeqStore).pos).wrapping_add(1);
1537 (*rawSeqStore).pos;
1538 return sequence;
1539 }
1540 if remaining <= sequence.litLength {
1541 sequence.offset = 0;
1542 } else if remaining < (sequence.litLength).wrapping_add(sequence.matchLength) {
1543 sequence.matchLength = remaining.wrapping_sub(sequence.litLength);
1544 if sequence.matchLength < minMatch {
1545 sequence.offset = 0;
1546 }
1547 }
1548 ZSTD_ldm_skipSequences(rawSeqStore, remaining as size_t, minMatch);
1549 sequence
1550}
1551pub unsafe fn ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore: *mut RawSeqStore_t, nbBytes: size_t) {
1552 let mut currPos = ((*rawSeqStore).posInSequence).wrapping_add(nbBytes) as u32;
1553 while currPos != 0 && (*rawSeqStore).pos < (*rawSeqStore).size {
1554 let currSeq = *((*rawSeqStore).seq).add((*rawSeqStore).pos);
1555 if currPos >= (currSeq.litLength).wrapping_add(currSeq.matchLength) {
1556 currPos = currPos.wrapping_sub((currSeq.litLength).wrapping_add(currSeq.matchLength));
1557 (*rawSeqStore).pos = ((*rawSeqStore).pos).wrapping_add(1);
1558 (*rawSeqStore).pos;
1559 } else {
1560 (*rawSeqStore).posInSequence = currPos as size_t;
1561 break;
1562 }
1563 }
1564 if currPos == 0 || (*rawSeqStore).pos == (*rawSeqStore).size {
1565 (*rawSeqStore).posInSequence = 0;
1566 }
1567}
1568pub unsafe fn ZSTD_ldm_blockCompress(
1569 rawSeqStore: *mut RawSeqStore_t,
1570 ms: *mut ZSTD_MatchState_t,
1571 seqStore: *mut SeqStore_t,
1572 rep: *mut u32,
1573 useRowMatchFinder: ZSTD_ParamSwitch_e,
1574 src: *const core::ffi::c_void,
1575 srcSize: size_t,
1576) -> size_t {
1577 let cParams: *const ZSTD_compressionParameters = &mut (*ms).cParams;
1578 let minMatch = (*cParams).minMatch;
1579 let blockCompressor = ZSTD_selectBlockCompressor(
1580 (*cParams).strategy,
1581 useRowMatchFinder,
1582 ZSTD_matchState_dictMode(ms),
1583 );
1584 let istart = src as *const u8;
1585 let iend = istart.add(srcSize);
1586 let mut ip = istart;
1587 if (*cParams).strategy as core::ffi::c_uint
1588 >= ZSTD_btopt as core::ffi::c_int as core::ffi::c_uint
1589 {
1590 let mut lastLLSize: size_t = 0;
1591 (*ms).ldmSeqStore = rawSeqStore;
1592 lastLLSize = blockCompressor.unwrap_unchecked()(ms, seqStore, rep, src, srcSize);
1593 ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize);
1594 return lastLLSize;
1595 }
1596 while (*rawSeqStore).pos < (*rawSeqStore).size && ip < iend {
1597 let sequence = maybeSplitSequence(
1598 rawSeqStore,
1599 iend.offset_from(ip) as core::ffi::c_long as u32,
1600 minMatch,
1601 );
1602 if sequence.offset == 0 {
1603 break;
1604 }
1605 ZSTD_ldm_limitTableUpdate(ms, ip);
1606 ZSTD_ldm_fillFastTables(ms, ip as *const core::ffi::c_void);
1607 let mut i: core::ffi::c_int = 0;
1608 let newLitLength = blockCompressor.unwrap_unchecked()(
1609 ms,
1610 seqStore,
1611 rep,
1612 ip as *const core::ffi::c_void,
1613 sequence.litLength as size_t,
1614 );
1615 ip = ip.offset(sequence.litLength as isize);
1616 i = ZSTD_REP_NUM - 1;
1617 while i > 0 {
1618 *rep.offset(i as isize) = *rep.offset((i - 1) as isize);
1619 i -= 1;
1620 }
1621 *rep.offset(0) = sequence.offset;
1622 ZSTD_storeSeq(
1623 seqStore,
1624 newLitLength,
1625 ip.offset(-(newLitLength as isize)),
1626 iend,
1627 (sequence.offset).wrapping_add(ZSTD_REP_NUM as u32),
1628 sequence.matchLength as size_t,
1629 );
1630 ip = ip.offset(sequence.matchLength as isize);
1631 }
1632 ZSTD_ldm_limitTableUpdate(ms, ip);
1633 ZSTD_ldm_fillFastTables(ms, ip as *const core::ffi::c_void);
1634 blockCompressor.unwrap_unchecked()(
1635 ms,
1636 seqStore,
1637 rep,
1638 ip as *const core::ffi::c_void,
1639 iend.offset_from(ip) as size_t,
1640 )
1641}