use super::bars::EMBED_STAR_NOTE;
use crate::commands::format::{fmt_elapsed, format_with_commas};
use colored::Colorize;
#[derive(Debug, Default, Clone, Copy)]
pub struct ReindexTimings {
pub walk_ms: u64,
pub parse_ms: u64,
pub embed_ms: u64,
pub bm25_ms: u64,
pub vector_upsert_ms: u64,
pub kg_ms: u64,
pub vector_count: u64,
pub symbol_count: u64,
pub edge_count: u64,
}
pub fn format_timing_breakdown(
t: &ReindexTimings,
total_chunks: u64,
elapsed_ms: u64,
defer_embed: bool,
lexical_only: bool,
) -> String {
let mut out = String::new();
if t.walk_ms > 0 {
out.push_str(&format!(
" {} {:>7}\n",
"File walk: ".dimmed(),
fmt_elapsed(t.walk_ms),
));
}
out.push_str(&format!(
" {} {:>7}\n",
"Wall-clock total:".bold(),
fmt_elapsed(elapsed_ms),
));
out.push_str(&format!(
" {}\n",
"Pipeline (overlapping \u{2014} subsystem times do not sum to total):".dimmed()
));
let parse_line = format!("{} {:>7}", "parse ".dimmed(), fmt_elapsed(t.parse_ms));
out.push_str(&format!(
" {} ({} chunks)\n",
parse_line,
format_with_commas(total_chunks),
));
if t.vector_count == 0 && total_chunks > 0 {
if lexical_only {
out.push_str(&format!(
" {} {}\n",
"embed ".dimmed(),
"SKIPPED (lexical-only index \u{2014} embedding disabled by config)"
.dimmed()
.bold(),
));
} else if !defer_embed {
let msg = "SKIPPED (embedder unresponsive or unreachable \u{2014} \
sidecar may be stalled or not running; BM25-only until re-indexed)";
out.push_str(&format!(
" {} {}\n",
"embed ".dimmed(),
msg.yellow().bold(),
));
}
} else {
let embed_line = format!("{} {:>7}", "embed ".dimmed(), fmt_elapsed(t.embed_ms));
out.push_str(&format!(
" {} ({} vectors)\n",
embed_line,
format_with_commas(t.vector_count),
));
}
let bm25_line = format!("{} {:>7}", "bm25 ".dimmed(), fmt_elapsed(t.bm25_ms));
if defer_embed && t.vector_count == 0 {
out.push_str(&format!(
" {} (vectors deferred to background embed pass)\n",
bm25_line,
));
} else {
let upsert_line = format!(
"{} {:>7}",
"upsert ".dimmed(),
fmt_elapsed(t.vector_upsert_ms)
);
out.push_str(&format!(
" {} \u{00b7} {} ({} vectors upserted)\n",
bm25_line,
upsert_line,
format_with_commas(t.vector_count),
));
}
let kg_line = format!(
"{} {:>7}",
"Knowledge graph (tail stage):".dimmed(),
fmt_elapsed(t.kg_ms)
);
out.push_str(&format!(
" {} ({} symbols, {} edges)\n",
kg_line,
format_with_commas(t.symbol_count),
format_with_commas(t.edge_count),
));
if t.vector_count > 0 {
out.push_str(&EMBED_STAR_NOTE.dimmed().to_string());
out.push('\n');
}
out
}
pub fn print_timing_breakdown(
t: &ReindexTimings,
total_chunks: u64,
elapsed_ms: u64,
defer_embed: bool,
lexical_only: bool,
) {
print!(
"{}",
format_timing_breakdown(t, total_chunks, elapsed_ms, defer_embed, lexical_only)
);
}