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:
1 parent
10a0909687
commit
bd7729b095
31 files changed
+1689
-178
No files matched your search
+13
-12
@@ -1,5 +1,6 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rayon::prelude::*;
|
||||
|
||||
@@ -88,22 +89,22 @@ fn layer_bytes(layer: &KmerLayer) -> LayerBytes {
|
||||
/// once up front — this is diagnostic tooling, not a hot path, so trading
|
||||
/// that eager open for not having to hand-reconstruct every layer's file
|
||||
/// paths is the right tradeoff here.
|
||||
pub struct BitsPerKmer<'a> {
|
||||
index: &'a KmerIndex,
|
||||
pub struct BitsPerKmer {
|
||||
index: Arc<KmerIndex>,
|
||||
}
|
||||
|
||||
impl<'a> BitsPerKmer<'a> {
|
||||
pub fn new(index: &'a KmerIndex) -> Self {
|
||||
impl BitsPerKmer {
|
||||
pub fn new(index: Arc<KmerIndex>) -> Self {
|
||||
Self { index }
|
||||
}
|
||||
}
|
||||
|
||||
impl Algorithm for BitsPerKmer<'_> {
|
||||
impl Algorithm for BitsPerKmer {
|
||||
type Output = IndexBitsPerKmer;
|
||||
|
||||
fn run(&mut self) -> obikalgorithm::Result<IndexBitsPerKmer> {
|
||||
let n_genomes = self.index.meta().genomes()?.len().max(1);
|
||||
let cache = IndexCache::new(self.index, None);
|
||||
let cache = IndexCache::new(Arc::clone(&self.index), None);
|
||||
let layers: Vec<&KmerLayer> = cache.iter().collect();
|
||||
|
||||
let (n_kmers, mphf_b, evidence_b, matrix_b) = layers
|
||||
@@ -148,23 +149,23 @@ impl Algorithm for BitsPerKmer<'_> {
|
||||
/// genome has a non-zero value (presence = 1, count > 0) — via
|
||||
/// `KmerLayer::col_weights` (`obicompactvec::ColumnWeights`), one call per
|
||||
/// layer instead of hand-opening each layer's matrix and summing rows.
|
||||
pub struct GenomeKmerCounts<'a> {
|
||||
index: &'a KmerIndex,
|
||||
pub struct GenomeKmerCounts {
|
||||
index: Arc<KmerIndex>,
|
||||
}
|
||||
|
||||
impl<'a> GenomeKmerCounts<'a> {
|
||||
pub fn new(index: &'a KmerIndex) -> Self {
|
||||
impl GenomeKmerCounts {
|
||||
pub fn new(index: Arc<KmerIndex>) -> Self {
|
||||
Self { index }
|
||||
}
|
||||
}
|
||||
|
||||
impl Algorithm for GenomeKmerCounts<'_> {
|
||||
impl Algorithm for GenomeKmerCounts {
|
||||
/// `(total_distinct_kmers, per_genome_kmer_counts)`.
|
||||
type Output = (usize, Vec<u64>);
|
||||
|
||||
fn run(&mut self) -> obikalgorithm::Result<(usize, Vec<u64>)> {
|
||||
let n_genomes = self.index.meta().genomes()?.len();
|
||||
let cache = IndexCache::new(self.index, None);
|
||||
let cache = IndexCache::new(Arc::clone(&self.index), None);
|
||||
let layers: Vec<&KmerLayer> = cache.iter().collect();
|
||||
|
||||
let total_kmers: usize = layers.iter().map(|l| l.n()).sum();
|
||||
|
||||
Reference in new issue
Block a user