mirror of
https://github.com/danog/ytop.git
synced 2024-11-26 20:15:03 +01:00
Implement process sorting and grouping
This commit is contained in:
parent
43b1ef7f68
commit
8b149e65ae
@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Group processes by default
|
||||||
|
|
||||||
## 0.1.0 - 2020-01-13
|
## 0.1.0 - 2020-01-13
|
||||||
|
|
||||||
Initial release!
|
Initial release!
|
||||||
|
@ -11,9 +11,16 @@ use crate::colorscheme::Colorscheme;
|
|||||||
use crate::update::UpdatableWidget;
|
use crate::update::UpdatableWidget;
|
||||||
use crate::widgets::block;
|
use crate::widgets::block;
|
||||||
|
|
||||||
|
enum ProcSorting {
|
||||||
|
Cpu,
|
||||||
|
Mem,
|
||||||
|
Num,
|
||||||
|
Command,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Proc {
|
struct Proc {
|
||||||
pid: u32,
|
num: u32,
|
||||||
name: String,
|
name: String,
|
||||||
commandline: String,
|
commandline: String,
|
||||||
cpu: f32,
|
cpu: f32,
|
||||||
@ -25,9 +32,12 @@ pub struct ProcWidget<'a> {
|
|||||||
update_interval: Ratio<u64>,
|
update_interval: Ratio<u64>,
|
||||||
colorscheme: &'a Colorscheme,
|
colorscheme: &'a Colorscheme,
|
||||||
|
|
||||||
|
grouping: bool,
|
||||||
selected_row: usize,
|
selected_row: usize,
|
||||||
|
sorting: ProcSorting,
|
||||||
|
|
||||||
procs: Vec<Proc>,
|
procs: Vec<Proc>,
|
||||||
|
grouped_procs: HashMap<String, Proc>,
|
||||||
processes: HashMap<u32, process::Process>,
|
processes: HashMap<u32, process::Process>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,9 +48,12 @@ impl ProcWidget<'_> {
|
|||||||
update_interval: Ratio::from_integer(1),
|
update_interval: Ratio::from_integer(1),
|
||||||
colorscheme,
|
colorscheme,
|
||||||
|
|
||||||
|
grouping: true,
|
||||||
selected_row: 0,
|
selected_row: 0,
|
||||||
|
sorting: ProcSorting::Cpu,
|
||||||
|
|
||||||
procs: Vec::new(),
|
procs: Vec::new(),
|
||||||
|
grouped_procs: HashMap::new(),
|
||||||
processes: HashMap::new(),
|
processes: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +82,7 @@ impl UpdatableWidget for ProcWidget<'_> {
|
|||||||
let result = {
|
let result = {
|
||||||
let name = process.name()?;
|
let name = process.name()?;
|
||||||
Ok(Proc {
|
Ok(Proc {
|
||||||
pid: process.pid(),
|
num: process.pid(),
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
commandline: process.cmdline()?.unwrap_or_else(|| format!("[{}]", name)),
|
commandline: process.cmdline()?.unwrap_or_else(|| format!("[{}]", name)),
|
||||||
cpu: process.cpu_percent()?,
|
cpu: process.cpu_percent()?,
|
||||||
@ -84,6 +97,21 @@ impl UpdatableWidget for ProcWidget<'_> {
|
|||||||
.filter_map(|process: process::ProcessResult<Proc>| process.ok())
|
.filter_map(|process: process::ProcessResult<Proc>| process.ok())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
self.grouped_procs = HashMap::new();
|
||||||
|
for proc in self.procs.iter() {
|
||||||
|
self.grouped_procs
|
||||||
|
.entry(proc.name.clone())
|
||||||
|
.and_modify(|e| {
|
||||||
|
e.num += 1;
|
||||||
|
e.cpu += proc.cpu;
|
||||||
|
e.mem += proc.mem;
|
||||||
|
})
|
||||||
|
.or_insert_with(|| Proc {
|
||||||
|
num: 1,
|
||||||
|
..proc.clone()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
for id in to_remove {
|
for id in to_remove {
|
||||||
self.processes.remove(&id);
|
self.processes.remove(&id);
|
||||||
}
|
}
|
||||||
@ -96,16 +124,35 @@ impl UpdatableWidget for ProcWidget<'_> {
|
|||||||
|
|
||||||
impl Widget for ProcWidget<'_> {
|
impl Widget for ProcWidget<'_> {
|
||||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||||
let mut procs = self.procs.clone();
|
let mut procs = if self.grouping {
|
||||||
procs.sort_by(|a, b| a.cpu.partial_cmp(&b.cpu).unwrap());
|
self.grouped_procs.values().cloned().collect()
|
||||||
|
} else {
|
||||||
|
self.procs.clone()
|
||||||
|
};
|
||||||
|
procs.sort_by(|a, b| match &self.sorting {
|
||||||
|
ProcSorting::Cpu => a.cpu.partial_cmp(&b.cpu).unwrap(),
|
||||||
|
ProcSorting::Mem => a.mem.partial_cmp(&b.mem).unwrap(),
|
||||||
|
ProcSorting::Num => a.num.cmp(&b.num),
|
||||||
|
ProcSorting::Command => a.commandline.cmp(&b.commandline),
|
||||||
|
});
|
||||||
|
|
||||||
Table::new(
|
Table::new(
|
||||||
["PID", "Command", "CPU%", "Mem%"].iter(),
|
[
|
||||||
|
if self.grouping { "Count" } else { "PID" },
|
||||||
|
"Command",
|
||||||
|
"CPU%",
|
||||||
|
"Mem%",
|
||||||
|
]
|
||||||
|
.iter(),
|
||||||
procs.into_iter().map(|proc| {
|
procs.into_iter().map(|proc| {
|
||||||
Row::StyledData(
|
Row::StyledData(
|
||||||
vec![
|
vec![
|
||||||
proc.pid.to_string(),
|
proc.num.to_string(),
|
||||||
proc.commandline,
|
if self.grouping {
|
||||||
|
proc.name
|
||||||
|
} else {
|
||||||
|
proc.commandline
|
||||||
|
},
|
||||||
format!("{:2.1}", proc.cpu),
|
format!("{:2.1}", proc.cpu),
|
||||||
format!("{:2.1}", proc.mem),
|
format!("{:2.1}", proc.mem),
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user