refactor: Shift KmerIndex ownership to Arc for thread-safe sharing

Replaces lifetime-bound references with runtime reference counting across multiple crates. This enables safe concurrent access across parallel workers without explicit cloning or manual lifetime management. Introduces the `query` and `utils` CLI commands in obikmer2, along with supporting modules for batch processing, sparse indexing, sliding-window findere logic, and output formatting. Updates dependency manifests and aligns test suites with the new ownership model.
This commit is contained in:
Eric Coissac
2026-08-28 19:32:45 +02:00
parent 10a0909687
commit bd7729b095
31 changed files with 1689 additions and 178 deletions
+4 -3
View File
@@ -1,4 +1,5 @@
use std::io::Write;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use rayon::prelude::*;
@@ -39,7 +40,7 @@ pub trait IndexDump {
) -> OKIResult<()>;
}
impl IndexDump for KmerIndex {
impl IndexDump for Arc<KmerIndex> {
fn dump<W: Write, F: Fn() + Send + Sync>(
&self,
out: &mut W,
@@ -87,7 +88,7 @@ impl IndexDump for KmerIndex {
Ok(_) => { write_row(buf, row, prefix); true }
}
};
let cache = IndexCache::new(self, Some(vec![i]));
let cache = IndexCache::new(Arc::clone(self), Some(vec![i]));
if debug {
cache.iter_partition_kmers_located(i, use_counts, n_genomes, filters, |part, layer, kmer, row| {
let seq = String::from_utf8(kmer.to_ascii()).unwrap_or_else(|_| "?".repeat(kmer_size));
@@ -106,7 +107,7 @@ impl IndexDump for KmerIndex {
// ── Unbounded: no atomic, no contention ───────────────────────────
(0..n).into_par_iter().map(|i| {
let mut buf = Vec::<u8>::new();
let cache = IndexCache::new(self, Some(vec![i]));
let cache = IndexCache::new(Arc::clone(self), Some(vec![i]));
if debug {
cache.iter_partition_kmers_located(i, use_counts, n_genomes, filters, |part, layer, kmer, row| {
let seq = String::from_utf8(kmer.to_ascii()).unwrap_or_else(|_| "?".repeat(kmer_size));
+3 -2
View File
@@ -5,6 +5,7 @@
//! foreign type, so this is an extension trait rather than an inherent `impl`.
use std::io::Write;
use std::sync::Arc;
use obidebruinj::GraphDeBruijn;
use obifastwrite::write_unitig;
@@ -25,7 +26,7 @@ pub trait IndexUnitigs {
) -> OKIResult<usize>;
}
impl IndexUnitigs for KmerIndex {
impl IndexUnitigs for Arc<KmerIndex> {
fn write_unitigs<W: Write + Send, F: Fn() + Send + Sync>(
&self,
out: &mut W,
@@ -40,7 +41,7 @@ impl IndexUnitigs for KmerIndex {
let g = (0..n)
.into_par_iter()
.try_fold(GraphDeBruijn::new, |mut local_g, i| -> OKIResult<GraphDeBruijn> {
let cache = IndexCache::new(self, Some(vec![i]));
let cache = IndexCache::new(Arc::clone(self), Some(vec![i]));
cache.iter_partition_kmers(i, use_counts, n_genomes, filters, |kmer, _row| {
local_g.push(kmer);
true