summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClementTsang <clementjhtsang@gmail.com>2020-01-08 00:28:11 -0500
committerClementTsang <clementjhtsang@gmail.com>2020-01-08 00:28:11 -0500
commit6cf8f0d98f750b6fb4c406de6ca0e37305692988 (patch)
tree91c0764e71af6885c128f4431e6da05c57b4f43c
parent0f2b4a7ba519d6a4d2e7c1dc212894551f98ce8b (diff)
Traded some mem + cpu for more smoothness while toggling.
-rw-r--r--src/app/data_collection.rs3
-rw-r--r--src/canvas.rs7
-rw-r--r--src/data_conversion.rs47
-rw-r--r--src/main.rs126
4 files changed, 123 insertions, 60 deletions
diff --git a/src/app/data_collection.rs b/src/app/data_collection.rs
index b44d02d9..3c7d9c70 100644
--- a/src/app/data_collection.rs
+++ b/src/app/data_collection.rs
@@ -32,7 +32,8 @@ pub struct Data {
pub swap: Vec<mem::MemData>,
pub list_of_temperature_sensor: Vec<temperature::TempData>,
pub network: Vec<network::NetworkData>,
- pub list_of_processes: Vec<processes::ProcessData>, // Only need to keep a list of processes...
+ pub list_of_processes: Vec<processes::ProcessData>,
+ pub grouped_list_of_processes: Option<Vec<processes::ProcessData>>,
pub list_of_disks: Vec<disks::DiskData>, // Only need to keep a list of disks and their data
}
diff --git a/src/canvas.rs b/src/canvas.rs
index 0c9e75d8..6df1a8e6 100644
--- a/src/canvas.rs
+++ b/src/canvas.rs
@@ -54,6 +54,7 @@ pub struct CanvasData {
pub disk_data: Vec<Vec<String>>,
pub temp_sensor_data: Vec<Vec<String>>,
pub process_data: Vec<ConvertedProcessData>,
+ pub grouped_process_data: Vec<ConvertedProcessData>,
pub memory_labels: Vec<(u64, u64)>,
pub mem_data: Vec<(f64, f64)>,
pub swap_data: Vec<(f64, f64)>,
@@ -747,7 +748,11 @@ fn draw_disk_table<B: backend::Backend>(
fn draw_processes_table<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
- let process_data: &[ConvertedProcessData] = &(app_state.canvas_data.process_data);
+ let process_data: &[ConvertedProcessData] = if app_state.is_grouped() {
+ &app_state.canvas_data.grouped_process_data
+ } else {
+ &app_state.canvas_data.process_data
+ };
// Admittedly this is kinda a hack... but we need to:
// * Scroll
diff --git a/src/data_conversion.rs b/src/data_conversion.rs
index cdc3100b..fd505e80 100644
--- a/src/data_conversion.rs
+++ b/src/data_conversion.rs
@@ -136,11 +136,13 @@ pub fn update_disk_row(app_data: &data_collection::Data) -> Vec<Vec<String>> {
disk_vector
}
-pub fn update_process_row(app_data: &data_collection::Data) -> Vec<ConvertedProcessData> {
- let mut process_vector: Vec<ConvertedProcessData> = Vec::new();
-
- for process in &app_data.list_of_processes {
- process_vector.push(ConvertedProcessData {
+pub fn update_process_row(
+ app_data: &data_collection::Data,
+) -> (Vec<ConvertedProcessData>, Vec<ConvertedProcessData>) {
+ let process_vector: Vec<ConvertedProcessData> = app_data
+ .list_of_processes
+ .iter()
+ .map(|process| ConvertedProcessData {
pid: process.pid,
name: process.command.to_string(),
cpu_usage: format!("{:.1}%", process.cpu_usage_percent),
@@ -163,10 +165,41 @@ pub fn update_process_row(app_data: &data_collection::Data) -> Vec<ConvertedProc
} else {
0
},
- });
+ })
+ .collect::<Vec<_>>();
+
+ let mut grouped_process_vector: Vec<ConvertedProcessData> = Vec::new();
+ if let Some(grouped_list_of_processes) = &app_data.grouped_list_of_processes {
+ grouped_process_vector = grouped_list_of_processes
+ .iter()
+ .map(|process| ConvertedProcessData {
+ pid: process.pid,
+ name: process.command.to_string(),
+ cpu_usage: format!("{:.1}%", process.cpu_usage_percent),
+ mem_usage: format!(
+ "{:.1}%",
+ if let Some(mem_usage) = process.mem_usage_percent {
+ mem_usage
+ } else if let Some(mem_usage_kb) = process.mem_usage_kb {
+ if let Some(mem_data) = app_data.memory.last() {
+ (mem_usage_kb / 1000) as f64 / mem_data.mem_total_in_mb as f64 * 100_f64
+ } else {
+ 0_f64
+ }
+ } else {
+ 0_f64
+ }
+ ),
+ group_count: if let Some(pid_vec) = &process.pid_vec {
+ pid_vec.len() as u32
+ } else {
+ 0
+ },
+ })
+ .collect::<Vec<_>>();
}
- process_vector
+ (process_vector, grouped_process_vector)
}
pub fn update_cpu_data_points(
diff --git a/src/main.rs b/src/main.rs
index ff4e300e..e04760af 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -260,12 +260,7 @@ fn main() -> error::Result<()> {
}
if app.to_be_resorted {
- data_collection::processes::sort_processes(
- &mut app.data.list_of_processes,
- &app.process_sorting_type,
- app.process_sorting_reverse,
- );
- app.canvas_data.process_data = update_process_row(&app.data);
+ handle_process_sorting(&mut app);
app.to_be_resorted = false;
}
}
@@ -280,50 +275,7 @@ fn main() -> error::Result<()> {
if !app.is_frozen {
app.data = *data;
- if app.is_grouped() {
- // Handle combining multi-pid processes to form one entry in table.
- // This was done this way to save time and avoid code
- // duplication... sorry future me. Really.
-
- // First, convert this all into a BTreeMap. The key is by name. This
- // pulls double duty by allowing us to combine entries AND it sorts!
-
- // Fields for tuple: CPU%, MEM%, PID_VEC
- let mut process_map: BTreeMap<String, (f64, f64, Vec<u32>)> =
- BTreeMap::new();
- for process in &app.data.list_of_processes {
- if let Some(mem_usage) = process.mem_usage_percent {
- let entry_val = process_map
- .entry(process.command.clone())
- .or_insert((0.0, 0.0, vec![]));
-
- entry_val.0 += process.cpu_usage_percent;
- entry_val.1 += mem_usage;
- entry_val.2.push(process.pid);
- }
- }
-
- // Now... turn this back into the exact same vector... but now with merged processes!
- app.data.list_of_processes = process_map
- .iter()
- .map(|(name, data)| {
- ProcessData {
- pid: 0, // Irrelevant
- cpu_usage_percent: data.0,
- mem_usage_percent: Some(data.1),
- mem_usage_kb: None,
- command: name.clone(),
- pid_vec: Some(data.2.clone()),
- }
- })
- .collect::<Vec<_>>();
- }
-
- data_collection::processes::sort_processes(
- &mut app.data.list_of_processes,
- &app.process_sorting_type,
- app.process_sorting_reverse,
- );
+ handle_process_sorting(&mut app);
// Convert all data into tui components
let network_data = update_network_data_points(&app.data);
@@ -336,12 +288,12 @@ fn main() -> error::Result<()> {
app.canvas_data.disk_data = update_disk_row(&app.data);
app.canvas_data.temp_sensor_data =
update_temp_row(&app.data, &app.temperature_type);
- app.canvas_data.process_data = update_process_row(&app.data);
app.canvas_data.mem_data = update_mem_data_points(&app.data);
app.canvas_data.memory_labels = update_mem_data_values(&app.data);
app.canvas_data.swap_data = update_swap_data_points(&app.data);
app.canvas_data.cpu_data =
update_cpu_data_points(app.show_average_cpu, &app.data);
+
//debug!("Update event complete.");
}
}
@@ -359,6 +311,78 @@ fn main() -> error::Result<()> {
Ok(())
}
+type TempProcess = (f64, Option<f64>, Option<u64>, Vec<u32>);
+
+fn handle_process_sorting(app: &mut app::App) {
+ // Handle combining multi-pid processes to form one entry in table.
+ // This was done this way to save time and avoid code
+ // duplication... sorry future me. Really.
+
+ // First, convert this all into a BTreeMap. The key is by name. This
+ // pulls double duty by allowing us to combine entries AND it sorts!
+
+ // Fields for tuple: CPU%, MEM%, MEM_KB, PID_VEC
+ let mut process_map: BTreeMap<String, TempProcess> = BTreeMap::new();
+ for process in &app.data.list_of_processes {
+ let entry_val =
+ process_map
+ .entry(process.command.clone())
+ .or_insert((0.0, None, None, vec![]));
+ if let Some(mem_usage) = process.mem_usage_percent {
+ entry_val.0 += process.cpu_usage_percent;
+ if let Some(m) = &mut entry_val.1 {
+ *m += mem_usage;
+ }
+ entry_val.3.push(process.pid);
+ } else if let Some(mem_usage_kb) = process.mem_usage_kb {
+ entry_val.0 += process.cpu_usage_percent;
+ if let Some(m) = &mut entry_val.2 {
+ *m += mem_usage_kb;
+ }
+ entry_val.3.push(process.pid);
+ }
+ }
+
+ // Now... turn this back into the exact same vector... but now with merged processes!
+ app.data.grouped_list_of_processes = Some(
+ process_map
+ .iter()
+ .map(|(name, data)| {
+ ProcessData {
+ pid: 0, // Irrelevant
+ cpu_usage_percent: data.0,
+ mem_usage_percent: data.1,
+ mem_usage_kb: data.2,
+ command: name.clone(),
+ pid_vec: Some(data.3.clone()),
+ }
+ })
+ .collect::<Vec<_>>(),
+ );
+
+ if let Some(grouped_list_of_processes) = &mut app.data.grouped_list_of_processes {
+ data_collection::processes::sort_processes(
+ grouped_list_of_processes,
+ if let data_collection::processes::ProcessSorting::PID = &app.process_sorting_type {
+ &data_collection::processes::ProcessSorting::CPU // Go back to default, negate PID for group
+ } else {
+ &app.process_sorting_type
+ },
+ app.process_sorting_reverse,
+ );
+ }
+
+ data_collection::processes::sort_processes(
+ &mut app.data.list_of_processes,
+ &app.process_sorting_type,
+ app.process_sorting_reverse,
+ );
+
+ let tuple_results = update_process_row(&app.data);
+ app.canvas_data.process_data = tuple_results.0;
+ app.canvas_data.grouped_process_data = tuple_results.1;
+}
+
fn cleanup(
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
) -> error::Result<()> {