|
|
@@ -1,7 +1,7 @@
|
|
|
+use log::{info, warn};
|
|
|
use std::fs;
|
|
|
use std::io::{self, BufReader, BufWriter, Read, Write};
|
|
|
use std::path::{Path, PathBuf};
|
|
|
-use log::{info, warn};
|
|
|
|
|
|
mod cache;
|
|
|
mod genome_index;
|
|
|
@@ -15,20 +15,22 @@ use suffix::{build_lcp_kasai, build_suffix_array};
|
|
|
/// Pure computation: genome bytes → min_unique_len vector.
|
|
|
/// Separated so GenomeIndex can call it without going through build_with_cache.
|
|
|
fn build_min_unique_len(genome: &[u8]) -> Vec<usize> {
|
|
|
- let n = genome.len();
|
|
|
- let sa = build_suffix_array(genome);
|
|
|
+ let n = genome.len();
|
|
|
+ let sa = build_suffix_array(genome);
|
|
|
let lcp = build_lcp_kasai(genome, &sa);
|
|
|
|
|
|
let mut rank = vec![0usize; n];
|
|
|
- for (i, &s) in sa.iter().enumerate() { rank[s] = i; }
|
|
|
+ for (i, &s) in sa.iter().enumerate() {
|
|
|
+ rank[s] = i;
|
|
|
+ }
|
|
|
|
|
|
let mut mul = vec![usize::MAX; n];
|
|
|
for p in 0..n {
|
|
|
- let r = rank[p];
|
|
|
- let left = if r > 0 { lcp[r] } else { 0 };
|
|
|
+ let r = rank[p];
|
|
|
+ let left = if r > 0 { lcp[r] } else { 0 };
|
|
|
let right = if r + 1 < n { lcp[r + 1] } else { 0 };
|
|
|
- let k = left.max(right) + 1;
|
|
|
- mul[p] = if p + k <= n { k } else { usize::MAX };
|
|
|
+ let k = left.max(right) + 1;
|
|
|
+ mul[p] = if p + k <= n { k } else { usize::MAX };
|
|
|
}
|
|
|
mul
|
|
|
}
|
|
|
@@ -66,7 +68,7 @@ impl UniquenessIndex {
|
|
|
if cache_path.exists() {
|
|
|
match load_from_cache(&cache_path, genome.len()) {
|
|
|
Ok(mul) => return Ok(Self::from_raw(mul)),
|
|
|
- Err(e) => warn!("[cache] invalid ({e}), rebuilding..."),
|
|
|
+ Err(e) => warn!("[cache] invalid ({e}), rebuilding..."),
|
|
|
}
|
|
|
}
|
|
|
let mul = build_min_unique_len(genome);
|
|
|
@@ -548,8 +550,7 @@ mod tests {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- use crate::helpers::test_init;
|
|
|
-
|
|
|
+ use crate::helpers::test_init;
|
|
|
|
|
|
#[test]
|
|
|
fn uniqueness_genome() -> anyhow::Result<()> {
|