#[non_exhaustive]pub struct CtprofDiff {Show 14 fields
pub sort_metric_name: Option<&'static str>,
pub rows: Vec<DiffRow>,
pub only_baseline: Vec<String>,
pub only_candidate: Vec<String>,
pub fudged_pairs: Vec<FudgedPair>,
pub cgroup_stats_a: BTreeMap<String, CgroupStats>,
pub cgroup_stats_b: BTreeMap<String, CgroupStats>,
pub host_psi_a: Psi,
pub host_psi_b: Psi,
pub smaps_rollup_a: BTreeMap<String, BTreeMap<String, u64>>,
pub smaps_rollup_b: BTreeMap<String, BTreeMap<String, u64>>,
pub sched_ext_a: Option<SchedExtSysfs>,
pub sched_ext_b: Option<SchedExtSysfs>,
pub derived_rows: Vec<DerivedRow>,
}Expand description
Full comparison result.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.sort_metric_name: Option<&'static str>§rows: Vec<DiffRow>§only_baseline: Vec<String>Group keys that appeared in the baseline snapshot but not
in the candidate, AFTER fudging removes pairs that joined
via thread-population overlap. Post-fudge survivors only
— keys that were rejoined to a candidate counterpart
move into Self::fudged_pairs and drop out of this
list.
only_candidate: Vec<String>Group keys that appeared in the candidate snapshot but not
in the baseline, AFTER fudging. Post-fudge survivors only;
same semantics as Self::only_baseline for the
candidate side.
fudged_pairs: Vec<FudgedPair>Cgroup pairs joined together via thread-population overlap
(Jaccard ≥ 0.90 over (pcomm, comm) thread-type sets).
Each entry is one matched (baseline, candidate) cgroup
pair plus its overlap / Jaccard / residuals / cascade
metadata. Pairs are emitted by the fudge stage of
super::compare() and consumed by the renderer’s “Fudged cgroup
matches” section. Empty except under super::GroupBy::All
(fudge runs only when group_by == GroupBy::All, matching
on the cgroup prefix of each compound key).
cgroup_stats_a: BTreeMap<String, CgroupStats>Baseline-only cgroup-level enrichment rows, keyed by the
cgroup path (after flatten). Populated only for
super::GroupBy::Cgroup.
cgroup_stats_b: BTreeMap<String, CgroupStats>Candidate-only cgroup-level enrichment rows, same shape.
host_psi_a: PsiBaseline host-level Pressure Stall Information snapshot.
Always populated (independent of super::GroupBy) — host-level
PSI surfaces above the per-thread table for any compare,
not just cgroup-grouped ones.
host_psi_b: PsiCandidate host-level PSI snapshot.
smaps_rollup_a: BTreeMap<String, BTreeMap<String, u64>>Baseline per-process smaps_rollup maps. Default
normalization keys by the token-normalized pcomm
(pattern_key(&t.pcomm)) — ephemeral PIDs across snapshots
collapse into one bucket per pcomm pattern (e.g.
worker-{N}), and the tgid is intentionally NOT part of
the key (every PID for a given pcomm pattern shares a
bucket; per-field byte counts SUM at
super::collect_smaps_rollup when multiple PIDs collapse).
Keys match the primary-table Pcomm group keys WHEN ≥2
processes share the same pattern (firefox,
kworker/{N}:{N}, worker-{N}, …). Singleton digit
pcomms diverge intentionally: the primary table reverts
the bucket key to the literal pcomm (e.g. worker-7)
when only one process matches the skeleton — see
super::build_groups’s singleton-revert gate — while smaps
stays normalized (worker-{N}) regardless of bucket
size, so cross-snapshot rows still join when PIDs are
ephemeral. The asymmetry is documented on
super::collect_smaps_rollup and is load-bearing for
memory-leak diffing across reboots; correlation between
the smaps row and the primary table happens via the
shared pcomm pattern, not always via byte-identical keys.
With super::CompareOptions::no_thread_normalize set, keys
preserve the literal pcomm[tgid] shape so each PID stays
attributable to its specific process instance — the
[tgid] is preserved precisely so two distinct PIDs
sharing a pcomm don’t collide within a snapshot. Rows
only join across snapshots when the same process instance
ran on both sides, which is the price of literal mode.
Populated from the per-thread leader rows of the
snapshot (tid == tgid; see crate::ctprof::ThreadState::smaps_rollup_kib).
smaps_rollup_b: BTreeMap<String, BTreeMap<String, u64>>Candidate per-process smaps_rollup maps, same shape and
normalization rules as Self::smaps_rollup_a.
sched_ext_a: Option<SchedExtSysfs>Baseline global sched_ext sysfs snapshot. None when
the baseline kernel had no /sys/kernel/sched_ext/
directory (CONFIG_SCHED_CLASS_EXT=n build).
sched_ext_b: Option<SchedExtSysfs>Candidate global sched_ext sysfs snapshot, same shape.
derived_rows: Vec<DerivedRow>One row per (matched group, derived metric) pair. Each
derivation in super::CTPROF_DERIVED_METRICS consumes
already-aggregated input metrics from the group’s
metrics map (see ThreadGroup::metrics) and produces a
scalar f64 with its own unit. None-valued sides
signal “not computable” — either the input metric was
missing on that side (capture-time CONFIG gate not set,
jemalloc not linked) or the formula’s denominator was
zero. Surfaced by super::write_diff in the dedicated
## Derived metrics section after the main table.
Trait Implementations§
Source§impl Clone for CtprofDiff
impl Clone for CtprofDiff
Source§fn clone(&self) -> CtprofDiff
fn clone(&self) -> CtprofDiff
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for CtprofDiff
impl Debug for CtprofDiff
Source§impl Default for CtprofDiff
impl Default for CtprofDiff
Source§fn default() -> CtprofDiff
fn default() -> CtprofDiff
Auto Trait Implementations§
impl Freeze for CtprofDiff
impl RefUnwindSafe for CtprofDiff
impl Send for CtprofDiff
impl Sync for CtprofDiff
impl Unpin for CtprofDiff
impl UnwindSafe for CtprofDiff
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more