use std::path::PathBuf;
use std::sync::Arc;
use crate::core::{
embed::Embedder,
indexer::CodeIndexer,
store::{UsearchStore, VectorStore},
};
use crate::service::persistence;
pub async fn build_indexer_with_persisted_state(
index_id: &str,
root_path: PathBuf,
embedder: &Arc<dyn Embedder>,
) -> CodeIndexer {
let dim = embedder.dimension();
let store: Arc<dyn VectorStore> = build_store(index_id, dim).await;
let mut indexer =
CodeIndexer::new(index_id, root_path).with_components(Arc::clone(embedder), store);
match persistence::chunks_path(index_id) {
Ok(path) => match indexer.load_chunks_from_disk(&path).await {
Ok(n) if n > 0 => tracing::info!(
"warm-boot: restored {} chunks for index '{}' from {}",
n,
index_id,
path.display()
),
Ok(_) => {} Err(e) => tracing::warn!(
"warm-boot: could not load chunks for '{}' ({e}) — starting empty",
index_id
),
},
Err(e) => tracing::warn!("cannot resolve chunks path for '{index_id}': {e}"),
}
let _ = &mut indexer;
indexer
}
async fn build_store(index_id: &str, dim: usize) -> Arc<dyn VectorStore> {
let path = match persistence::hnsw_path(index_id) {
Ok(p) => p,
Err(e) => {
tracing::warn!("cannot resolve hnsw path for '{index_id}': {e}");
return fresh_store(dim);
}
};
if persistence::has_persisted_hnsw(&path) {
match UsearchStore::load_from(&path).await {
Ok(Some(store)) => {
if store.dim() == dim {
tracing::info!(
"warm-boot: restored HNSW snapshot for '{}' from {}",
index_id,
path.display()
);
return Arc::new(store);
}
tracing::warn!(
"warm-boot: hnsw snapshot for '{}' has dim {} but embedder is {} — starting fresh",
index_id,
store.dim(),
dim
);
}
Ok(None) => {
tracing::warn!(
"warm-boot: hnsw snapshot at {} could not be loaded — starting fresh",
path.display()
);
}
Err(e) => {
tracing::warn!(
"warm-boot: error loading hnsw snapshot at {}: {e} — starting fresh",
path.display()
);
}
}
}
fresh_store(dim)
}
fn fresh_store(dim: usize) -> Arc<dyn VectorStore> {
let s = UsearchStore::new(dim).unwrap_or_else(|e| {
tracing::error!(
"failed to allocate UsearchStore (dim={dim}): {e} — daemon cannot continue"
);
panic!("usearch alloc failure (OOM during HNSW init, dim={dim}): {e}");
});
Arc::new(s) as Arc<dyn VectorStore>
}