Skip to content

fix(bam): prevent duplicate reads from indexed CRAM queries - #178

Draft
NicoDeVeaux wants to merge 5 commits into
ndv/fix-pr118-unmapped-sweepfrom
ndv/fix-pr118-cram-multiref-fetch
Draft

NicoDeVeaux wants to merge 5 commits into
ndv/fix-pr118-unmapped-sweepfrom
ndv/fix-pr118-cram-multiref-fetch

Conversation

@NicoDeVeaux

@NicoDeVeaux NicoDeVeaux commented Oct 23, 2026 •

Copy link
Copy Markdown

Indexed CRAM fetches now keep only the requested reference's records and query each reference/container once. This fixes two duplicate-read paths in noodles 0.94.0: multi-reference slices yielded other references' records, and multiple CRAI slice entries for the same reference/container caused the whole container to be decoded repeatedly.

The query index retains one entry per (reference ID, container offset) when opening the reader and when rebuilding it with a reference FASTA. Records are not deduplicated by name: repeated names can represent distinct physical records and must remain present. The shim queries complete references; the per-record reference filter is preserved.

This remains stacked on #177 (ndv/fix-pr118-unmapped-sweep) for the #118 migration. The updated head includes #177's empty-unmapped-sweep fix through an ordinary merge, preserving both public branch histories. Both PRs should be incorporated into #118 before the migration lands.

Validation of be3976 on macOS arm64 / Rust 1.90.0:

  • All 244 release tests pass: 208 library, 12 binary, 22 integration and two doc tests. Formatting and strict Clippy pass.
  • The original six-record multi-reference CRAM matches samtools at one and four threads instead of counting records from other references again.
  • A new valid, samtools-checked two-slice same-reference CRAM contains six physical records, including repeated names. The previous public head returned ten records; the fixed reader returns six. Reader and CLI regressions cover it at one and four threads and compare all 16 flagstat rows with samtools 1.22.1.
  • Exact native head/version and executable-byte bindings pass from a regular clone. A prior worktree build-metadata instability was retained separately; it was not a CRAM test failure.

A separate CI follow-up pins crossbeam-epoch 0.9.20 and replaces an equivalent iterator-exhaustion match with ? for newer stable Clippy. Fresh Linux/upstream CI, package/security validation and a full RNA corpus remain separate checks. #175's counting-candidate Linux evidence does not transfer to this noodles build; integrating those branches requires resolving conflicts and verifying the resulting source. No read-level deduplication, noodles version bump or exit-policy change is introduced.

This update is written by GPT-6 on Nico DeVeaux's behalf. The original PR was prepared with Claude Code.

NicoDeVeaux and others added 2 commits October 23, 2026 11:55
… records

In a multi-reference CRAM slice, `fetch(tid)` returns every record in the
slice whose position overlaps the (whole-reference) interval, whatever its
reference: noodles' query filters on the interval only. On the parallel
path each such record is counted once per reference fetch (flagstat
"in total" 10 instead of 6 for the samtools-written fixture at --threads 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
noodles' CRAM `query` filters records on the interval only, so in a
multi-reference slice `fetch(tid)` also returned other references'
records whose positions fall inside the whole-reference interval. Keep
only records whose reference sequence ID is `tid`, as htslib does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Retain the public PR178 ancestry and updated PR177 fixes. Resolve append-only test and fixture documentation conflicts by keeping both complete regressions.
@NicoDeVeaux NicoDeVeaux changed the title fix(bam): per-reference CRAM fetch keeps only that reference's records fix(bam): prevent duplicate reads from indexed CRAM queries Nov 1, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant