use std::borrow::Borrow;
use crate::model::ProcessSnapshot;
mod filter;
mod sort;
mod subtree;
mod tree;
#[cfg(test)]
mod fixtures;
pub use filter::{FilterPattern, PlainPattern, ProcessFilter, ProcessPredicate};
pub use sort::{ProcessSort, ProcessSortKey, SortDirection, UnknownSortKey};
pub use subtree::{Coverage, SubtreeUsage, Summed};
pub use tree::{ProcessTree, TreeRow};
#[must_use]
pub fn flat_order<P: Borrow<ProcessSnapshot>>(
processes: &[P],
filter: &ProcessFilter,
sort: ProcessSort,
) -> Vec<usize> {
let mut rows: Vec<(usize, &ProcessSnapshot)> = processes
.iter()
.map(Borrow::borrow)
.enumerate()
.filter(|(_, process)| filter.matches(process))
.collect();
rows.sort_by(|(_, left), (_, right)| sort.compare(left, right));
rows.into_iter().map(|(index, _)| index).collect()
}
#[cfg(test)]
mod tests {
use super::fixtures::process;
use super::*;
use crate::model::ProcessState;
#[test]
fn the_flat_view_filters_before_it_sorts() {
let processes = vec![
process(1, 1).name("systemd").cpu(1.0).build(),
process(2, 2).name("rustc").cpu(50.0).build(),
process(3, 3).name("rustc").cpu(90.0).build(),
];
let order = flat_order(
&processes,
&ProcessFilter::parse("rustc"),
ProcessSort::default(),
);
assert_eq!(order, vec![2, 1], "only rustc rows, hottest first");
}
#[test]
fn an_inactive_filter_keeps_every_row() {
let processes = vec![
process(1, 1).cpu(1.0).build(),
process(2, 2).cpu(2.0).build(),
];
let order = flat_order(&processes, &ProcessFilter::new(), ProcessSort::default());
assert_eq!(order.len(), processes.len());
}
#[test]
fn the_flat_view_accepts_borrowed_rows_without_cloning_them() {
let processes = [
process(7, 7).cpu(5.0).build(),
process(8, 8).cpu(9.0).build(),
];
let borrowed: Vec<&ProcessSnapshot> = processes.iter().collect();
let order = flat_order(&borrowed, &ProcessFilter::new(), ProcessSort::default());
assert_eq!(order, vec![1, 0]);
}
#[test]
fn composed_toggles_and_text_all_apply_to_the_flat_view() {
let processes = vec![
process(1, 1)
.name("kworker/0:1")
.user(0, Some("root"))
.kernel_thread()
.build(),
process(2, 2).name("cargo").user(501, Some("gabor")).build(),
process(3, 3).name("cargo").user(0, Some("root")).build(),
process(4, 4)
.name("zsh")
.user(501, Some("gabor"))
.state(ProcessState::Sleeping)
.build(),
];
let filter = ProcessFilter::parse("cargo")
.with_only_user(Some(501))
.with_hidden_kernel_threads(true);
let order = flat_order(&processes, &filter, ProcessSort::default());
assert_eq!(order, vec![1]);
}
}