Skip to main content

libzstd_rs_sys/lib/compress/
zstd_ldm.rs

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        // Loose bound, should be around 1<<29 (see above)
386        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}