refactor: refactor some process grouping code (#1727)

Remove one clone for process grouping.
This commit is contained in:
Clement Tsang 2025-05-10 18:24:06 -04:00 committed by GitHub
parent 33e070bfa3
commit 134888dfec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 43 additions and 51 deletions

View File

@ -19,7 +19,7 @@ use crate::{
/// TODO: Maybe reduce visibility of internal data, make it only accessible through DataStore? /// TODO: Maybe reduce visibility of internal data, make it only accessible through DataStore?
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StoredData { pub struct StoredData {
pub last_update_time: Instant, // FIXME: (points_rework_v1) remove this? pub last_update_time: Instant, // FIXME: (points_rework_v1) we could be able to remove this with some more refactoring.
pub timeseries_data: TimeSeriesData, pub timeseries_data: TimeSeriesData,
pub network_harvest: network::NetworkHarvest, pub network_harvest: network::NetworkHarvest,
pub ram_harvest: Option<MemData>, pub ram_harvest: Option<MemData>,

View File

@ -112,25 +112,6 @@ pub struct ProcessHarvest {
// pub virt_kb: u64, // pub virt_kb: u64,
} }
impl ProcessHarvest {
pub(crate) fn add(&mut self, rhs: &ProcessHarvest) {
self.cpu_usage_percent += rhs.cpu_usage_percent;
self.mem_usage_bytes += rhs.mem_usage_bytes;
self.mem_usage_percent += rhs.mem_usage_percent;
self.read_bytes_per_sec += rhs.read_bytes_per_sec;
self.write_bytes_per_sec += rhs.write_bytes_per_sec;
self.total_read_bytes += rhs.total_read_bytes;
self.total_write_bytes += rhs.total_write_bytes;
self.time = self.time.max(rhs.time);
#[cfg(feature = "gpu")]
{
self.gpu_mem += rhs.gpu_mem;
self.gpu_util += rhs.gpu_util;
self.gpu_mem_percent += rhs.gpu_mem_percent;
}
}
}
impl DataCollector { impl DataCollector {
pub(crate) fn get_processes(&mut self) -> CollectionResult<Vec<ProcessHarvest>> { pub(crate) fn get_processes(&mut self) -> CollectionResult<Vec<ProcessHarvest>> {
cfg_if! { cfg_if! {

View File

@ -270,7 +270,7 @@ fn create_collection_thread(
}) })
} }
/// Main code to call. /// Main code to call to start bottom.
#[inline] #[inline]
pub fn start_bottom(enable_error_hook: &mut bool) -> anyhow::Result<()> { pub fn start_bottom(enable_error_hook: &mut bool) -> anyhow::Result<()> {
// let _profiler = dhat::Profiler::new_heap(); // let _profiler = dhat::Profiler::new_heap();
@ -367,8 +367,9 @@ pub fn start_bottom(enable_error_hook: &mut bool) -> anyhow::Result<()> {
panic::set_hook(Box::new(panic_hook)); panic::set_hook(Box::new(panic_hook));
// Set termination hook // Set termination hook
// TODO: On UNIX, use signal-hook to handle cleanup as well.
ctrlc::set_handler(move || { ctrlc::set_handler(move || {
// TODO: Consider using signal-hook (https://github.com/vorner/signal-hook) to handle
// more types of signals?
let _ = sender.send(BottomEvent::Terminate); let _ = sender.send(BottomEvent::Terminate);
})?; })?;
@ -381,9 +382,7 @@ pub fn start_bottom(enable_error_hook: &mut bool) -> anyhow::Result<()> {
loop { loop {
if let Ok(recv) = receiver.recv() { if let Ok(recv) = receiver.recv() {
match recv { match recv {
BottomEvent::Terminate => { BottomEvent::Terminate => break,
break;
}
BottomEvent::Resize => { BottomEvent::Resize => {
try_drawing(&mut terminal, &mut app, &mut painter)?; try_drawing(&mut terminal, &mut app, &mut painter)?;
} }

View File

@ -676,7 +676,8 @@ impl ProcWidgetState {
let mut id_pid_map: HashMap<String, Vec<Pid>> = HashMap::default(); let mut id_pid_map: HashMap<String, Vec<Pid>> = HashMap::default();
let mut filtered_data: Vec<ProcWidgetData> = if let ProcWidgetMode::Grouped = self.mode { let mut filtered_data: Vec<ProcWidgetData> = if let ProcWidgetMode::Grouped = self.mode {
let mut id_process_mapping: HashMap<&String, ProcessHarvest> = HashMap::default(); let mut id_process_mapping: HashMap<&String, ProcWidgetData> = HashMap::default();
for process in filtered_iter { for process in filtered_iter {
let id = if is_using_command { let id = if is_using_command {
&process.command &process.command
@ -691,30 +692,46 @@ impl ProcWidgetState {
id_pid_map.insert(id.clone(), vec![pid]); id_pid_map.insert(id.clone(), vec![pid]);
} }
if let Some(grouped_process_harvest) = id_process_mapping.get_mut(id) { if let Some(pwd) = id_process_mapping.get_mut(id) {
grouped_process_harvest.add(process); pwd.cpu_usage_percent += process.cpu_usage_percent;
} else {
// FIXME: [PERF] could maybe eliminate an allocation here in the grouped mode... match &mut pwd.mem_usage {
// or maybe just avoid the entire transformation step, making an alloc fine. MemUsage::Percent(usage) => {
id_process_mapping.insert(id, process.clone()); *usage += process.mem_usage_percent;
}
MemUsage::Bytes(usage) => {
*usage += process.mem_usage_bytes;
} }
} }
id_process_mapping pwd.rps += process.read_bytes_per_sec;
.values() pwd.wps += process.write_bytes_per_sec;
.map(|process| { pwd.total_read += process.total_read_bytes;
let id = if is_using_command { pwd.total_write += process.total_write_bytes;
&process.command pwd.time = pwd.time.max(process.time);
#[cfg(feature = "gpu")]
{
pwd.gpu_usage += process.gpu_util;
match &mut pwd.gpu_mem_usage {
MemUsage::Percent(usage) => {
*usage += process.gpu_mem_percent;
}
MemUsage::Bytes(usage) => {
*usage += process.gpu_mem;
}
}
}
pwd.num_similar += 1;
} else { } else {
&process.name id_process_mapping.insert(
}; id,
ProcWidgetData::from_data(process, is_using_command, is_mem_percent),
);
}
}
let num_similar = id_pid_map.get(id).map(|val| val.len()).unwrap_or(1) as u64; id_process_mapping.into_values().collect()
ProcWidgetData::from_data(process, is_using_command, is_mem_percent)
.num_similar(num_similar)
})
.collect()
} else { } else {
filtered_iter filtered_iter
.map(|process| ProcWidgetData::from_data(process, is_using_command, is_mem_percent)) .map(|process| ProcWidgetData::from_data(process, is_using_command, is_mem_percent))

View File

@ -259,11 +259,6 @@ impl ProcWidgetData {
} }
} }
pub fn num_similar(mut self, num_similar: u64) -> Self {
self.num_similar = num_similar;
self
}
pub fn disabled(mut self, disabled: bool) -> Self { pub fn disabled(mut self, disabled: bool) -> Self {
self.disabled = disabled; self.disabled = disabled;
self self