Add configurable sparsity flag to index finalization and merge CLI
Extends `KmerIndex::finalize_indexed` to accept a `sparse` boolean parameter, enabling control over whether output presence matrices are packed in a compact sparse format or stored densely. The merge command now exposes a `--dense` flag to invert this setting, defaulting to the existing sparse representation. Call sites in select and rebuild modules pass `false` to preserve current behavior. A benchmark lock file is also added for dependency tracking.
This commit is contained in:
@@ -52,9 +52,10 @@ pub trait IndexBuilder: Sized {
|
|||||||
|
|
||||||
/// Mark `output` as fully indexed, pack its column matrices, and reopen it.
|
/// Mark `output` as fully indexed, pack its column matrices, and reopen it.
|
||||||
///
|
///
|
||||||
/// Shared tail of the `select`/`rebuild` construction paths, once their
|
/// Shared tail of the `select`/`rebuild`/`merge` construction paths,
|
||||||
/// partitions have been written.
|
/// once their partitions have been written. `sparse` selects the
|
||||||
fn finalize_indexed<P: AsRef<Path>>(output: P, rep: &mut Reporter) -> OKIResult<Self>;
|
/// on-disk presence-matrix format (see `pack_matrices`).
|
||||||
|
fn finalize_indexed<P: AsRef<Path>>(output: P, rep: &mut Reporter, sparse: bool) -> OKIResult<Self>;
|
||||||
|
|
||||||
/// Current construction state, read fresh from `index.meta` (see
|
/// Current construction state, read fresh from `index.meta` (see
|
||||||
/// `DevDocMD/implementation/partition_layer_cache.md`, "(11)" — no
|
/// `DevDocMD/implementation/partition_layer_cache.md`, "(11)" — no
|
||||||
@@ -99,12 +100,12 @@ impl IndexBuilder for KmerIndex {
|
|||||||
Ok(idx)
|
Ok(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalize_indexed<P: AsRef<Path>>(output: P, rep: &mut Reporter) -> OKIResult<Self> {
|
fn finalize_indexed<P: AsRef<Path>>(output: P, rep: &mut Reporter, sparse: bool) -> OKIResult<Self> {
|
||||||
let output = output.as_ref();
|
let output = output.as_ref();
|
||||||
let idx = KmerIndex::open(output)?;
|
let idx = KmerIndex::open(output)?;
|
||||||
idx.meta.mark_indexed().map_err(OKIError::Io)?;
|
idx.meta.mark_indexed().map_err(OKIError::Io)?;
|
||||||
let t_pack = Stage::start("pack");
|
let t_pack = Stage::start("pack");
|
||||||
idx.pack_matrices(false)?;
|
idx.pack_matrices(sparse)?;
|
||||||
rep.push(t_pack.stop());
|
rep.push(t_pack.stop());
|
||||||
Ok(idx)
|
Ok(idx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ pub struct MergeArgs {
|
|||||||
/// Disambiguate duplicate genome labels by appending .1, .2, … instead of erroring
|
/// Disambiguate duplicate genome labels by appending .1, .2, … instead of erroring
|
||||||
#[arg(long, default_value_t = false)]
|
#[arg(long, default_value_t = false)]
|
||||||
pub rename_duplicates: bool,
|
pub rename_duplicates: bool,
|
||||||
|
|
||||||
|
/// Pack the output's presence matrices in the dense format instead of the default sparse one
|
||||||
|
#[arg(long, default_value_t = false)]
|
||||||
|
pub dense: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(args: MergeArgs) {
|
pub fn run(args: MergeArgs) {
|
||||||
@@ -89,6 +93,7 @@ pub fn run(args: MergeArgs) {
|
|||||||
let mut merge = Merge::new(&source_refs, &args.output, mode)
|
let mut merge = Merge::new(&source_refs, &args.output, mode)
|
||||||
.force(args.force)
|
.force(args.force)
|
||||||
.rename_duplicates(args.rename_duplicates)
|
.rename_duplicates(args.rename_duplicates)
|
||||||
|
.sparse(!args.dense)
|
||||||
.on_progress(|_: Progress| pb.inc(1));
|
.on_progress(|_: Progress| pb.inc(1));
|
||||||
|
|
||||||
let dst = merge.run().unwrap_or_else(|e| {
|
let dst = merge.run().unwrap_or_else(|e| {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ pub struct Merge<'a> {
|
|||||||
mode: MergeMode,
|
mode: MergeMode,
|
||||||
force: bool,
|
force: bool,
|
||||||
rename_duplicates: bool,
|
rename_duplicates: bool,
|
||||||
|
sparse: bool,
|
||||||
reporter: Reporter,
|
reporter: Reporter,
|
||||||
on_progress: Option<Box<dyn FnMut(Progress) + Send + 'a>>,
|
on_progress: Option<Box<dyn FnMut(Progress) + Send + 'a>>,
|
||||||
}
|
}
|
||||||
@@ -57,6 +58,7 @@ impl<'a> Merge<'a> {
|
|||||||
mode,
|
mode,
|
||||||
force: false,
|
force: false,
|
||||||
rename_duplicates: false,
|
rename_duplicates: false,
|
||||||
|
sparse: true,
|
||||||
reporter: Reporter::new(),
|
reporter: Reporter::new(),
|
||||||
on_progress: None,
|
on_progress: None,
|
||||||
}
|
}
|
||||||
@@ -76,6 +78,13 @@ impl<'a> Merge<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pack the merged output's presence matrices in the compact sparse
|
||||||
|
/// format rather than dense (default: `true`).
|
||||||
|
pub fn sparse(mut self, v: bool) -> Self {
|
||||||
|
self.sparse = v;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Progress callback, called once per completed partition.
|
/// Progress callback, called once per completed partition.
|
||||||
pub fn on_progress(mut self, cb: impl FnMut(Progress) + Send + 'a) -> Self {
|
pub fn on_progress(mut self, cb: impl FnMut(Progress) + Send + 'a) -> Self {
|
||||||
self.on_progress = Some(Box::new(cb));
|
self.on_progress = Some(Box::new(cb));
|
||||||
@@ -322,7 +331,7 @@ impl Algorithm for Merge<'_> {
|
|||||||
|
|
||||||
// ── Finalize: pack matrices, mark indexed, reopen ──────────────────────
|
// ── Finalize: pack matrices, mark indexed, reopen ──────────────────────
|
||||||
let t = Stage::start("finalize");
|
let t = Stage::start("finalize");
|
||||||
let dst = KmerIndex::finalize_indexed(&output, &mut self.reporter)?;
|
let dst = KmerIndex::finalize_indexed(&output, &mut self.reporter, self.sparse)?;
|
||||||
self.reporter.push(t.stop());
|
self.reporter.push(t.stop());
|
||||||
|
|
||||||
Ok(dst)
|
Ok(dst)
|
||||||
|
|||||||
@@ -74,6 +74,6 @@ impl KmerIndex {
|
|||||||
|
|
||||||
rep.push(t.stop());
|
rep.push(t.stop());
|
||||||
|
|
||||||
KmerIndex::finalize_indexed(output, rep)
|
KmerIndex::finalize_indexed(output, rep, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ impl KmerIndex {
|
|||||||
pb.finish_and_clear();
|
pb.finish_and_clear();
|
||||||
rep.push(t.stop());
|
rep.push(t.stop());
|
||||||
|
|
||||||
KmerIndex::finalize_indexed(output, rep)
|
KmerIndex::finalize_indexed(output, rep, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rewrite the genome columns of this index in-place according to `specs`.
|
/// Rewrite the genome columns of this index in-place according to `specs`.
|
||||||
|
|||||||
Reference in New Issue
Block a user