feat: add convert command for in-place index evidence modification

Introduce a new CLI command that modifies existing indices to support exact, approximate, or hybrid evidence modes. This change enables the reindex module in obikrebuild, exposing an IndexReindex trait for evidence persistence and layer processing. It also refactors obikindexer to publicly expose an IndexBuilder trait for post-build evidence construction, while adding a set_evidence API in obikindex to safely update configuration fields without altering core parameters.
This commit is contained in:
Eric Coissac
2026-08-28 19:43:14 +02:00
parent bd7729b095
commit 4ea3cd32ba
10 changed files with 562 additions and 340 deletions
+22 -23
View File
@@ -218,29 +218,28 @@ impl IndexMeta {
self.write_full(&on_disk)
}
// /// Overwrite `config` and the whole `genomes` list at once, preserving
// /// `state`. `config` otherwise never changes once an index exists —
// /// this is the deliberate, rare exception for construction paths that
// /// legitimately rewrite it in place (`select_in_place`, `reindex`).
// /// The caller must refresh its own cached `Arc<IndexMeta>` afterward
// /// (e.g. `self.meta = Arc::new(IndexMeta::open(self)?)`) — this method
// /// only updates the file, it has no way to reach back into whatever
// /// `KmerIndex` holds it.
// /// TODO: This methode is strange
// pub(crate) fn rewrite_config(
// &self,
// config: IndexConfig,
// genomes: Vec<GenomeInfo>,
// ) -> io::Result<()> {
// let _guard = self.lock.write().unwrap();
// let state = Self::read_full(&self.root_path)?.state;
// self.write_full(&IndexMetadata {
// version: self.version,
// config,
// genomes,
// state,
// })
// }
/// Update the evidence representation in place — `evidence`, and (for
/// `Exact`) its block size. The only `IndexConfig` fields a reindex is
/// ever allowed to touch: `kmer_size`/`minimizer_size`/`n_bits`/
/// `with_counts` are baked into the already-built MPHF/unitigs/matrices
/// and can never change post-build, unlike the evidence bundle, which
/// is derived from `unitigs.bin` + `mphf.bin` alone and can be
/// rebuilt in a different form at any time (see
/// `obikindexer::IndexBuilder`).
///
/// The caller must refresh its own cached `Arc<IndexMeta>` afterward
/// (e.g. `self.meta = Arc::new(IndexMeta::open(self)?)`) — this method
/// only updates the file, it has no way to reach back into whatever
/// `KmerIndex` holds it.
pub fn set_evidence(&self, evidence: IndexMode, block_bits: u8) -> io::Result<()> {
let _guard = self.lock.write().unwrap();
let mut on_disk = Self::read_full(&self.root_path)?;
on_disk.config.evidence = evidence;
if matches!(on_disk.config.evidence, IndexMode::Exact) {
on_disk.config.block_bits = block_bits;
}
self.write_full(&on_disk)
}
pub fn set_state(&self, state: IndexState) -> io::Result<()> {
let _guard = self.lock.write().unwrap();