mod cgroup;
mod derived;
mod host_psi;
mod orphans;
mod primary;
mod sched_ext;
mod smaps;
use std::fmt;
use std::path::Path;
use super::columns::Column;
use super::diff_types::CtprofDiff;
use super::options::GroupBy;
use super::render::{colored_header_with_sort, render_derived_row_cells, render_diff_row_cells};
use super::runner::DisplayOptions;
pub fn write_diff<W: fmt::Write>(
w: &mut W,
diff: &CtprofDiff,
baseline_path: &Path,
candidate_path: &Path,
group_by: GroupBy,
display: &DisplayOptions,
) -> fmt::Result {
let group_header = match group_by {
GroupBy::Pcomm => "pcomm",
GroupBy::Cgroup => "cgroup",
GroupBy::Comm => "comm-pattern",
GroupBy::CommExact => "comm",
GroupBy::All => "comm",
};
let mut columns = display.resolved_compare_columns();
let has_sort_col = diff.rows.first().is_some_and(|r| r.sort_by_cell.is_some());
if has_sort_col {
columns.push(Column::SortBy);
}
let global_max_widths: Vec<u16> = if group_by == GroupBy::All {
compute_global_max_widths(diff, &columns, display)
} else {
Vec::new()
};
primary::write_primary_section(
w,
diff,
group_by,
group_header,
&columns,
display,
&global_max_widths,
)?;
derived::write_derived_section(
w,
diff,
group_by,
group_header,
&columns,
display,
&global_max_widths,
)?;
smaps::write_smaps_section(w, diff, group_by, &columns, display, &global_max_widths)?;
cgroup::write_cgroup_sections(w, diff, group_by, display)?;
host_psi::write_host_psi_section(w, diff, display)?;
sched_ext::write_sched_ext_section(w, diff, display)?;
orphans::write_orphans_section(w, diff, baseline_path, candidate_path, group_by)?;
Ok(())
}
fn compute_global_max_widths(
diff: &CtprofDiff,
columns: &[Column],
display: &DisplayOptions,
) -> Vec<u16> {
let mut measure = display.new_table();
measure.set_header(colored_header_with_sort(
columns,
"comm",
diff.sort_metric_name,
));
for row in &diff.rows {
let mut cells = render_diff_row_cells(row, columns);
if let Some(pos) = columns.iter().position(|c| *c == Column::Group) {
let comm = row.group_key.splitn(3, '\x00').nth(2).unwrap_or("");
cells[pos] = comm.to_string();
}
measure.add_row(cells);
}
for row in &diff.derived_rows {
let mut cells = render_derived_row_cells(row, columns);
if let Some(pos) = columns.iter().position(|c| *c == Column::Group) {
let comm = row.group_key.splitn(3, '\x00').nth(2).unwrap_or("");
cells[pos] = comm.to_string();
}
measure.add_row(cells);
}
measure.column_max_content_widths()
}