mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-27 07:34:27 +02:00
refactor: refactor some process grouping code (#1727)
Remove one clone for process grouping.
This commit is contained in:
parent
33e070bfa3
commit
134888dfec
@ -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>,
|
||||||
|
@ -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! {
|
||||||
|
@ -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)?;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
match &mut pwd.mem_usage {
|
||||||
|
MemUsage::Percent(usage) => {
|
||||||
|
*usage += process.mem_usage_percent;
|
||||||
|
}
|
||||||
|
MemUsage::Bytes(usage) => {
|
||||||
|
*usage += process.mem_usage_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pwd.rps += process.read_bytes_per_sec;
|
||||||
|
pwd.wps += process.write_bytes_per_sec;
|
||||||
|
pwd.total_read += process.total_read_bytes;
|
||||||
|
pwd.total_write += process.total_write_bytes;
|
||||||
|
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 {
|
||||||
// FIXME: [PERF] could maybe eliminate an allocation here in the grouped mode...
|
id_process_mapping.insert(
|
||||||
// or maybe just avoid the entire transformation step, making an alloc fine.
|
id,
|
||||||
id_process_mapping.insert(id, process.clone());
|
ProcWidgetData::from_data(process, is_using_command, is_mem_percent),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
id_process_mapping
|
id_process_mapping.into_values().collect()
|
||||||
.values()
|
|
||||||
.map(|process| {
|
|
||||||
let id = if is_using_command {
|
|
||||||
&process.command
|
|
||||||
} else {
|
|
||||||
&process.name
|
|
||||||
};
|
|
||||||
|
|
||||||
let num_similar = id_pid_map.get(id).map(|val| val.len()).unwrap_or(1) as u64;
|
|
||||||
|
|
||||||
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))
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user