1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Shared, C-faithful lazy-parse decision logic.
//!
//! Upstream zstd has a SINGLE lazy parser — `ZSTD_compressBlock_lazy_generic`
//! (`lib/compress/zstd_lazy.c`) — parameterized by the search method
//! (hash-chain / binary-tree / row-hash) and the lookahead `depth`. The match
//! finders differ per strategy; the PARSE DECISION (how a candidate at the
//! current position is weighed against one a byte or two ahead) is identical
//! across all of them.
//!
//! This module hosts that one decision so the per-strategy matchers
//! (HC / Row / dfast) share it instead of each carrying a divergent copy. The
//! register-hungry part is the search kernel, which stays specialized per
//! strategy and is injected here as a closure — the decision itself is a
//! handful of comparisons per position, so sharing it adds no spill pressure.
/// C-faithful lazy commit/defer decision, ONE source for every strategy.
///
/// Expanded INLINE at the call site (like upstream's single
/// `FORCE_INLINE_TEMPLATE ZSTD_compressBlock_lazy_generic`, zstd_lazy.c:1516):
/// the strategy's match finder is spliced in directly, so it stays inlined
/// inside the caller's (target_feature) kernel — a `fn` taking the finder as a
/// closure de-inlines a `#[target_feature]` finder across the call boundary and
/// regressed the Row band ~6%; a macro does not.
///
/// Evaluates to `Option<Option<M>>`:
/// - `None` → COMMIT the current best match;
/// - `Some(carry)` → DEFER and carry `carry` (the one-ahead `Option<M>`) to the
/// next position so it is not re-searched (upstream searches each position
/// once). A caller that re-searches instead just tests `.is_none()`.
///
/// `search = |pos, lit| <expr>` is a SPLICE, not a closure: the macro inlines
/// `<expr>` with `pos` / `lit` bound, yielding `Option<M>` for any match `M`
/// with `.match_len` / `.offset` (`usize`). Mirrors zstd_lazy.c:1629-1700 — the
/// depth-1 lookahead defers when the one-ahead match is longer (ties go to the
/// smaller offset); the depth-2 one (only at `lazy_depth >= 2`) when it is
/// strictly more than +1 longer. This length heuristic is faster than upstream's
/// gain weighting and still beats C on ratio (drop-in, not binary parity). The
/// only early-outs are the out-of-bounds guard and the `target_len`
/// sufficient-length shortcut (pass `usize::MAX` to disable it).
pub use lazy_decide;