---
phase: 04-corealgo
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - src/parser.rs
autonomous: true
requirements:
  - ALGO-01
  - ALGO-02

must_haves:
  truths:
    - "LogIterator::next() 使用 FINDER_RECORD_START.find_iter 驱动扫描，不含 while let Some(idx) = memchr(b'\\n', ...) 逐行循环"
    - "find_next_record_start() 使用 FINDER_RECORD_START.find_iter 替代逐行 memchr loop"
    - "时间戳验证使用 is_timestamp_start() 函数（u64 掩码），不含 8 个独立字节比较分支"
    - "所有现有测试（cargo test）全部通过"
    - "benchmark 单线程吞吐相比 Phase 3 基线提升 ≥10%"
  artifacts:
    - path: "src/parser.rs"
      provides: "重写后的记录边界检测算法"
      contains: "FINDER_RECORD_START"
    - path: "src/parser.rs"
      provides: "u64 掩码时间戳验证"
      contains: "is_timestamp_start"
    - path: "src/parser.rs"
      provides: "掩码常量"
      contains: "LO_MASK"
  key_links:
    - from: "LogIterator::next()"
      to: "FINDER_RECORD_START.find_iter"
      via: "for candidate in FINDER_RECORD_START.find_iter(data)"
      pattern: "FINDER_RECORD_START\\.find_iter"
    - from: "find_next_record_start()"
      to: "FINDER_RECORD_START.find_iter"
      via: "for candidate in FINDER_RECORD_START.find_iter(&data[pos..])"
      pattern: "FINDER_RECORD_START\\.find_iter"
    - from: "is_timestamp_start()"
      to: "u64 掩码常量"
      via: "lo & LO_MASK == LO_EXPECTED"
      pattern: "LO_MASK"
---

<objective>
重写 `src/parser.rs` 中的记录边界检测核心算法，实现 Phase 4 的两项算法优化：

1. **ALGO-01（per D-01/D-02/D-03）**：以 `LazyLock<Finder<'static>>` 静态变量 `FINDER_RECORD_START` 驱动
   `memmem::find_iter(b"\n20")` 单次扫描，替换 `LogIterator::next()` 和
   `find_next_record_start()` 中的 `while let Some(idx) = memchr(b'\n', ...)` 逐行循环。

2. **ALGO-02（per D-04）**：提取 `is_timestamp_start()` 辅助函数，用两次 LE u64 load + 位掩码比较
   替换散落在两处的 8 个独立字节 if 分支，同时消除代码重复。

Purpose: 消除内层 memchr 逐行循环的逐字节开销，让 SIMD 子串搜索直接跳过无关字节，
预期实现单线程吞吐 ≥10% 的净提升。

Output: 修改后的 `src/parser.rs`，所有现有测试通过，benchmark 验证提升达标。
</objective>

<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/04-corealgo/04-CONTEXT.md
@.planning/phases/04-corealgo/04-RESEARCH.md
@.planning/phases/04-corealgo/04-PATTERNS.md
</context>

<interfaces>
<!-- 关键代码契约，executor 直接使用，无需额外探索 -->

<!-- 现有静态 Finder 模式（src/parser.rs:17-19） -->
```rust
/// Pre-built SIMD searcher for the `") "` meta-close pattern.
static FINDER_CLOSE_META: LazyLock<Finder<'static>> = LazyLock::new(|| Finder::new(b") "));
```

<!-- 需要新增的静态 Finder（紧接在 FINDER_CLOSE_META 之后，第 19 行之后） -->
```rust
/// Pre-built SIMD searcher for the `"\n20"` record-start pattern.
/// Shared across threads via LazyLock; constructed once on first use.
static FINDER_RECORD_START: LazyLock<Finder<'static>> =
    LazyLock::new(|| Finder::new(b"\n20"));
```

<!-- 需要添加的 u64 掩码常量和辅助函数（插入到 make_invalid_format_error 之前，约第 406 行） -->
```rust
// u64 掩码常量：验证时间戳格式 "20YY-MM-DD HH:MM:SS.mmm"
// 字节位置：0('2'), 1('0'), 4('-'), 7('-'), 10(' '), 13(':'), 16(':'), 19('.')
const LO_MASK: u64     = 0xFF0000FF0000FFFF; // data[0..8]：位置 0,1,4,7
const LO_EXPECTED: u64 = 0x2D00002D00003032; // LE: '2'=0x32,'0'=0x30,'-'=0x2D,'-'=0x2D
const HI_MASK: u64     = 0x0000FF0000FF0000; // data[8..16]：位置 10,13（偏移 2,5）
const HI_EXPECTED: u64 = 0x00003A0000200000; // LE: ' '=0x20,':'=0x3A

/// 检查 bytes[0..23] 是否符合时间戳格式 "20YY-MM-DD HH:MM:SS.mmm"。
/// 调用前需确保 bytes.len() >= 23（由调用方做长度检查）。
#[inline(always)]
fn is_timestamp_start(bytes: &[u8]) -> bool {
    debug_assert!(bytes.len() >= 23);
    let lo = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
    let hi = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
    // 位置 16(':') 和 19('.') 用两次单字节比较
    (lo & LO_MASK == LO_EXPECTED)
        && (hi & HI_MASK == HI_EXPECTED)
        && bytes[16] == b':'
        && bytes[19] == b'.'
}
```

<!-- parse_record_with_hint 签名（保持不变） -->
```rust
fn parse_record_with_hint<'a>(
    record_bytes: &'a [u8],
    is_multiline: bool,
    encoding_hint: FileEncodingHint,
) -> Result<Sqllog<'a>, ParseError>
```
</interfaces>

<tasks>

<task type="auto" tdd="true">
  <name>Task 1: 添加 FINDER_RECORD_START 和 is_timestamp_start()</name>
  <files>src/parser.rs</files>
  <read_first>
    - src/parser.rs（完整文件，尤其第 1–19 行 import/静态变量 和第 406–412 行辅助函数）
  </read_first>
  <behavior>
    - is_timestamp_start(b"2026-04-24 10:30:45.123rest") 返回 true（正例）
    - is_timestamp_start(b"1026-04-24 10:30:45.123rest") 返回 false（首字节非 '2'）
    - is_timestamp_start(b"20261104 10:30:45.123rest") 返回 false（位置 4 非 '-'）
    - is_timestamp_start(b"2026-04-24X10:30:45.123rest") 返回 false（位置 10 非 ' '）
    - is_timestamp_start(b"2026-04-24 10:30:45X123rest") 返回 false（位置 19 非 '.'）
    - FINDER_RECORD_START 能在 b"foo\n2026-04-24 10:30:00.000 ..." 中定位 '\n' 的位置
  </behavior>
  <action>
    在 src/parser.rs 中做以下两处插入：

    **插入 1 — FINDER_RECORD_START（第 19 行之后，紧接 FINDER_CLOSE_META）：**
    ```rust
    /// Pre-built SIMD searcher for the `"\n20"` record-start pattern.
    /// Shared across threads via LazyLock; constructed once on first use.
    static FINDER_RECORD_START: LazyLock<Finder<'static>> =
        LazyLock::new(|| Finder::new(b"\n20"));
    ```

    **插入 2 — 常量 + is_timestamp_start()（插入到 make_invalid_format_error 之前）：**
    ```rust
    // u64 掩码常量：验证时间戳格式 "20YY-MM-DD HH:MM:SS.mmm"
    // 字节位置：0('2'), 1('0'), 4('-'), 7('-'), 10(' '), 13(':'), 16(':'), 19('.')
    const LO_MASK: u64     = 0xFF0000FF0000FFFF; // data[0..8]：位置 0,1,4,7
    const LO_EXPECTED: u64 = 0x2D00002D00003032; // LE: '2'=0x32,'0'=0x30,'-'=0x2D,'-'=0x2D
    const HI_MASK: u64     = 0x0000FF0000FF0000; // data[8..16]：位置 10,13（偏移 2,5）
    const HI_EXPECTED: u64 = 0x00003A0000200000; // LE: ' '=0x20,':'=0x3A

    /// 检查 bytes[0..23] 是否符合时间戳格式 "20YY-MM-DD HH:MM:SS.mmm"。
    /// 调用前需确保 bytes.len() >= 23（由调用方做长度检查）。
    #[inline(always)]
    fn is_timestamp_start(bytes: &[u8]) -> bool {
        debug_assert!(bytes.len() >= 23);
        let lo = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
        let hi = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
        // 位置 16(':') 和 19('.') 用两次单字节比较（比第三次 u64 load 更清晰）
        (lo & LO_MASK == LO_EXPECTED)
            && (hi & HI_MASK == HI_EXPECTED)
            && bytes[16] == b':'
            && bytes[19] == b'.'
    }
    ```

    **注意（per ALGO-02 / D-04）：**
    - LO 窗口 bytes[0..8]：LE 字节序下 `u64` 的最低字节对应 bytes[0]。
      位置 0='2'(0x32)，1='0'(0x30)，4='-'(0x2D)，7='-'(0x2D)。
      LO_EXPECTED = 0x2D00002D00003032（验证方法：bytes[0..8] = [0x32,0x30,YY,YY,0x2D,MM,DD,0x2D]，
      from_le_bytes 结果为 0x2D_DD_MM_2D_YY_YY_30_32，用 LO_MASK=0xFF0000FF0000FFFF 掩掉可变部分）
    - HI 窗口 bytes[8..16]：bytes[10] 在 HI 中偏移为 2（bytes[8]对应偏移0），bytes[13] 偏移为 5。
      HI_EXPECTED = 0x00003A0000200000（' '=0x20 在偏移2，':'=0x3A 在偏移5）
    - bytes[16] == b':' 和 bytes[19] == b'.' 直接单字节比较，无需第三次 u64 load（per Claude's Discretion）
    - 函数体内只有 debug_assert!（不影响 release 性能）和两次 u64 from_le_bytes + 位运算
    - 使用 safe `try_into().unwrap()` 而非 unsafe 指针 cast（编译器会优化为 MOV 指令）
  </action>
  <verify>
    <automated>cargo test 2>&1 | tail -5</automated>
  </verify>
  <done>
    - src/parser.rs 包含 `static FINDER_RECORD_START`（grep 验证：`grep -n "FINDER_RECORD_START" src/parser.rs`）
    - src/parser.rs 包含 `fn is_timestamp_start` 和 `LO_MASK` 常量（grep 验证：`grep -n "is_timestamp_start\|LO_MASK" src/parser.rs`）
    - `cargo test` 全部通过（此时 is_timestamp_start 存在但尚未被主流程调用，不影响现有测试）
  </done>
</task>

<task type="auto">
  <name>Task 2: 重写 LogIterator::next() 和 find_next_record_start()</name>
  <files>src/parser.rs</files>
  <read_first>
    - src/parser.rs（完整文件，重点：第 113–183 行 LogIterator::next()、第 188–219 行 find_next_record_start()；在 Task 1 完成后读取，确保 FINDER_RECORD_START 和 is_timestamp_start 已存在）
  </read_first>
  <action>
    **替换 LogIterator::next() 内层扫描循环（第 120–153 行旧代码）：**

    将以下旧代码：
    ```rust
    let mut scan_pos = 0;
    let mut found_next = None;
    let mut is_multiline = false;

    while let Some(idx) = memchr(b'\n', &data[scan_pos..]) {
        let newline_idx = scan_pos + idx;
        let next_line_start = newline_idx + 1;
        if next_line_start >= data.len() { break; }
        let check_len = std::cmp::min(23, data.len() - next_line_start);
        if check_len == 23 {
            let next_bytes = &data[next_line_start..next_line_start + 23];
            if next_bytes[0] == b'2' && next_bytes[1] == b'0' && next_bytes[4] == b'-'
                && next_bytes[7] == b'-' && next_bytes[10] == b' ' && next_bytes[13] == b':'
                && next_bytes[16] == b':' && next_bytes[19] == b'.'
            {
                found_next = Some(newline_idx);
                break;
            }
        }
        is_multiline = true;
        scan_pos = next_line_start;
    }
    ```

    替换为（ALGO-01 + ALGO-02，per D-01/D-02/D-03）：
    ```rust
    // ALGO-01: memmem 单次扫描替代逐行 memchr 循环
    let mut found_boundary: Option<usize> = None;
    for candidate in FINDER_RECORD_START.find_iter(data) {
        // candidate 是 '\n' 的位置；candidate+1 是候选时间戳起始
        let ts_start = candidate + 1;
        if ts_start + 23 <= data.len()
            && is_timestamp_start(&data[ts_start..ts_start + 23])
        {
            found_boundary = Some(candidate);
            break;
        }
        // 验证失败：继续 find_iter 找下一个候选，由 find_iter 自动管理偏移
    }
    ```

    同时将其后的赋值语句（旧的 found_next / is_multiline 逻辑）替换为：
    ```rust
    let (record_end, next_start) = match found_boundary {
        Some(idx) => (idx, idx + 1),
        None => (data.len(), data.len()),
    };

    // D-02: is_multiline 通过 memchr 在确认的边界范围内检测内嵌换行
    // （保留 parse_record_with_hint 的单行快速路径）
    let is_multiline = memchr(b'\n', &data[..record_end]).is_some();
    ```

    后续代码（record_slice 赋值、self.pos 更新、CRLF trim、empty skip、parse_record_with_hint 调用）
    全部保持不变，只是将旧的 `found_next`/`record_end`/`next_start` 变量名改为新名称（record_end 和 next_start 语义相同）。

    ---

    **替换 find_next_record_start() 内层 loop（第 197–218 行旧代码）：**

    将以下旧代码（跳行首逻辑之后的 loop）：
    ```rust
    loop {
        if pos + 23 > data.len() { return data.len(); }
        let peek = &data[pos..pos + 23];
        if peek[0] == b'2' && peek[1] == b'0' && peek[4] == b'-'
            && peek[7] == b'-' && peek[10] == b' ' && peek[13] == b':'
            && peek[16] == b':' && peek[19] == b'.'
        {
            return pos;
        }
        match memchr(b'\n', &data[pos..]) {
            Some(nl) => pos += nl + 1,
            None => return data.len(),
        }
    }
    ```

    替换为（per D-01，保留 Pitfall 2 行首检测）：
    ```rust
    // 先检查 pos 本身是否是时间戳行（Finder 不会命中无前置 '\n' 的行首）
    if pos + 23 <= data.len() && is_timestamp_start(&data[pos..pos + 23]) {
        return pos;
    }

    // ALGO-01: memmem 单次扫描替代逐行 memchr loop
    for candidate in FINDER_RECORD_START.find_iter(&data[pos..]) {
        let ts_start = pos + candidate + 1;
        if ts_start + 23 <= data.len()
            && is_timestamp_start(&data[ts_start..ts_start + 23])
        {
            return ts_start;
        }
    }
    data.len()
    ```

    **注意（关键边界案例）：**
    - LogIterator::next() 中：`data = &self.data[self.pos..]`，所有偏移（found_boundary、record_end、next_start）
      均为相对于 `data` 的偏移，`self.pos += next_start` 使用相对偏移（防止 Pitfall 4）
    - find_next_record_start() 中：Finder 在 `&data[pos..]` 上搜索，candidate 是相对于该切片的偏移，
      故 `ts_start = pos + candidate + 1`（防止绝对/相对偏移混淆）
    - 调用 is_timestamp_start 前**始终**先做长度检查 `ts_start + 23 <= data.len()`（防止 Pitfall 3）
    - find_next_record_start() 的前置"跳到行首"代码（memchr + pos += nl + 1）保持不变
    - `memchr` import 必须保留（is_multiline 检测和 find_next_record_start 行首跳转仍在使用）
    - 不应在重写后代码中出现任何 `while let Some(idx) = memchr(b'\n', ...)` 驱动的循环（这是 ALGO-01 的核心目标）
  </action>
  <verify>
    <automated>cargo test 2>&1 && echo "ALL TESTS PASSED"</automated>
  </verify>
  <done>
    - `grep -n "while let Some.*memchr.*b.*n" src/parser.rs` 返回空（内层 memchr 逐行循环已消除）
    - `grep -n "FINDER_RECORD_START\.find_iter" src/parser.rs` 返回两条命中（LogIterator::next 和 find_next_record_start 各一处）
    - `grep -n "is_timestamp_start" src/parser.rs` 返回三条以上命中（函数定义 + 至少两处调用）
    - `cargo test` 全部通过
    - `cargo clippy -- -D warnings` 无警告
  </done>
</task>

<task type="checkpoint:human-verify" gate="blocking">
  <what-built>
    Task 1 添加了 FINDER_RECORD_START LazyLock 静态变量和 is_timestamp_start() u64 掩码辅助函数。
    Task 2 用 memmem find_iter 重写了 LogIterator::next() 和 find_next_record_start() 的核心扫描逻辑。
  </what-built>
  <how-to-verify>
    1. 运行完整测试套件，确认无回归：
       ```
       cargo test
       ```
       期望：所有测试通过，无 panic

    2. 运行覆盖率检查，确认不低于 90%：
       ```
       cargo llvm-cov --workspace --all-features --fail-under-lines 90
       ```
       期望：通过，覆盖率 ≥90%

    3. 运行 benchmark，对比 Phase 3 基线：
       ```
       cargo bench --bench parser_benchmark 2>&1 | grep -E "thrpt|time"
       ```
       期望：单线程吞吐相比 Phase 3 基线提升 ≥10%（records/sec 或 GB/s 指标）

    4. 运行回归门禁脚本（如存在）：
       ```
       bash scripts/check-regression.sh 2>/dev/null || echo "no script found"
       ```

    5. 确认内层 memchr 循环已消除：
       ```
       grep -n "while let Some.*memchr" src/parser.rs
       ```
       期望：无输出（返回空）
  </how-to-verify>
  <resume-signal>输入 "approved" 确认所有检查通过，或描述发现的问题</resume-signal>
</task>

</tasks>

<threat_model>
## Trust Boundaries

| Boundary | Description |
|----------|-------------|
| 文件内容→解析器 | mmap 内容来自不可信文件系统输入 |

## STRIDE Threat Register

| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-04-01 | Denial of Service | is_timestamp_start() | mitigate | debug_assert! + 调用前强制长度检查 `ts_start + 23 <= data.len()`，防止 panic；所有调用点均有边界守卫 |
| T-04-02 | Tampering | u64 from_le_bytes | accept | 使用 safe `try_into().unwrap()`，长度已由调用方保证；无 unsafe 字节 load，无 UB 风险 |
| T-04-03 | Denial of Service | FINDER_RECORD_START find_iter | accept | memmem 本身无递归，迭代器消耗 O(n)；SQL body 内 `\n20` 误报由 is_timestamp_start 过滤，最坏情况下多几次掩码验证 |
</threat_model>

<verification>
## Phase 4 完成验证

```bash
# 1. 所有单元测试和集成测试通过
cargo test

# 2. 覆盖率 ≥90%
cargo llvm-cov --workspace --all-features --fail-under-lines 90

# 3. 内层 memchr 逐行循环已消除（ALGO-01 核心目标）
grep -n "while let Some.*memchr" src/parser.rs
# 期望：无输出

# 4. memmem find_iter 在两处调用点存在
grep -c "FINDER_RECORD_START\.find_iter" src/parser.rs
# 期望：2

# 5. u64 掩码辅助函数存在（ALGO-02）
grep -n "fn is_timestamp_start\|LO_MASK\|LO_EXPECTED" src/parser.rs
# 期望：至少 3 行

# 6. benchmark 吞吐提升 ≥10%
cargo bench --bench parser_benchmark

# 7. clippy 无警告
cargo clippy -- -D warnings
```
</verification>

<success_criteria>
1. `grep "while let Some.*memchr" src/parser.rs` 返回空（内层逐行 memchr 循环彻底消除）
2. `grep -c "FINDER_RECORD_START\.find_iter" src/parser.rs` 输出 `2`（LogIterator::next 和 find_next_record_start 各一处）
3. `grep "fn is_timestamp_start" src/parser.rs` 返回一条命中
4. `cargo test` 全部通过（无回归）
5. `cargo llvm-cov --workspace --all-features --fail-under-lines 90` 通过（覆盖率 ≥90%）
6. benchmark 单线程吞吐相比 Phase 3 基线提升 ≥10%
</success_criteria>

<output>
完成后在 `.planning/phases/04-corealgo/` 中创建 `04-01-SUMMARY.md`，记录：
- 实际修改的代码区域和行号
- 最终 benchmark 数字（改动前 vs 改动后）
- 任何与 RESEARCH.md 预期不符的发现（如 is_multiline memchr 开销实测影响）
</output>
