From 99d4b94e5c23369a9f13ebedbb9b8a3251f6292d Mon Sep 17 00:00:00 2001 From: Marco De Araujo Date: Tue, 20 Jan 2026 16:18:54 -0400 Subject: [PATCH] optimizations --- src/core/data.rs | 37 ++++++++++++++++++------------- src/data/heartbeat/parser.rs | 4 ++-- src/data/status_page/parser.rs | 4 ++-- src/ui/app.rs | 13 ++++++----- src/ui/components/monitor_list.rs | 26 ++++++++++++---------- src/ui/dashboard/model.rs | 18 ++++++--------- 6 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/core/data.rs b/src/core/data.rs index 44fbd17..028515d 100644 --- a/src/core/data.rs +++ b/src/core/data.rs @@ -7,28 +7,35 @@ use crate::data::{ status_page::model::StatusPageResponse, }; -pub fn unify_data<'a>(status_page: &'a StatusPageResponse, heartbeat: &'a HeartbeatResponse) -> UnifiedData<'a> { +pub fn unify_data<'a>( + status_page: &'a StatusPageResponse, + heartbeat: &'a HeartbeatResponse, +) -> UnifiedData<'a> { let mut groups = Vec::with_capacity(status_page.public_group_list.len()); - let heartbeat_map: HashMap = heartbeat - .monitors - .iter() - .map(|m| (m.monitor_id, &m.heartbeats[..])) - .collect(); - let uptime_map: HashMap<(u64, u32), &'a UptimeData> = heartbeat - .uptime_data - .iter() - .map(|u| ((u.monitor_id, u.period_hours), u)) - .collect(); + let mut heartbeat_map: HashMap = + HashMap::with_capacity(heartbeat.monitors.len()); + heartbeat_map.extend( + heartbeat + .monitors + .iter() + .map(|m| (m.monitor_id, &m.heartbeats[..])), + ); + + let mut uptime_map: HashMap<(u64, u32), &'a UptimeData> = + HashMap::with_capacity(heartbeat.uptime_data.len()); + uptime_map.extend( + heartbeat + .uptime_data + .iter() + .map(|u| ((u.monitor_id, u.period_hours), u)), + ); for group in &status_page.public_group_list { let mut monitors = Vec::with_capacity(group.monitor_list.len()); for monitor_info in &group.monitor_list { let uptime_data = uptime_map.get(&(monitor_info.id, 24)).copied(); - let heartbeats = heartbeat_map - .get(&monitor_info.id) - .copied() - .unwrap_or(&[]); + let heartbeats = heartbeat_map.get(&monitor_info.id).copied().unwrap_or(&[]); let name: Cow<'a, str> = if monitor_info.name.len() > 100 { Cow::Owned(monitor_info.name.clone()) diff --git a/src/data/heartbeat/parser.rs b/src/data/heartbeat/parser.rs index 3733065..72e4bcd 100644 --- a/src/data/heartbeat/parser.rs +++ b/src/data/heartbeat/parser.rs @@ -3,8 +3,8 @@ use crate::i18n::t; use anyhow::{Context, Ok, Result}; pub fn parse_response(json_text: &str) -> Result { - let mut response: HeartbeatResponse = - serde_json::from_str(json_text).with_context(|| t("invalid-json-heartbeat"))?; + let mut response: HeartbeatResponse = serde_json::from_slice(json_text.as_bytes()) + .with_context(|| t("invalid-json-heartbeat"))?; response.process()?; Ok(response) diff --git a/src/data/status_page/parser.rs b/src/data/status_page/parser.rs index a765c58..b6b8c07 100644 --- a/src/data/status_page/parser.rs +++ b/src/data/status_page/parser.rs @@ -3,7 +3,7 @@ use crate::i18n::t; use anyhow::{Context, Ok, Result}; pub fn parse_response(json_text: &str) -> Result { - let response: StatusPageResponse = - serde_json::from_str(json_text).with_context(|| t("invalid-json-status-page"))?; + let response: StatusPageResponse = serde_json::from_slice(json_text.as_bytes()) + .with_context(|| t("invalid-json-status-page"))?; Ok(response) } diff --git a/src/ui/app.rs b/src/ui/app.rs index f9ab49f..a2abab4 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -30,6 +30,8 @@ use std::{ }; const INITIAL_INTERVAL: u32 = 300; +const MAIN_LAYOUT_WITH_SCROLLBAR: [Constraint; 2] = [Constraint::Min(1), Constraint::Length(1)]; +const MAIN_LAYOUT_WITHOUT_SCROLLBAR: [Constraint; 1] = [Constraint::Min(1)]; enum FetchResult { Heartbeat(Result), @@ -134,12 +136,11 @@ impl App { render_header(frame, chunks[0], &self.state); - let mut main_constraint = Vec::with_capacity(2); - main_constraint.push(Constraint::Min(1)); - - if self.state.show_vertical_scrollbar(chunks[1].height) { - main_constraint.push(Constraint::Length(1)); - } + let main_constraint = if self.state.show_vertical_scrollbar(chunks[1].height) { + &MAIN_LAYOUT_WITH_SCROLLBAR[..] + } else { + &MAIN_LAYOUT_WITHOUT_SCROLLBAR[..] + }; let main_chunks = Layout::default() .direction(Direction::Horizontal) diff --git a/src/ui/components/monitor_list.rs b/src/ui/components/monitor_list.rs index 56a8cfa..1cab664 100644 --- a/src/ui/components/monitor_list.rs +++ b/src/ui/components/monitor_list.rs @@ -137,11 +137,10 @@ fn render_monitor_table( let header = Row::new(header_cells).style(title_style()).height(1); - let rows: Vec = monitors - .iter() - .take(items_to_show) - .map(|monitor| create_monitor_item(monitor)) - .collect(); + let mut rows: Vec = Vec::with_capacity(items_to_show); + for monitor in monitors.iter().take(items_to_show) { + rows.push(create_monitor_item(monitor)); + } let widths = vec![ Constraint::Length(3), @@ -256,17 +255,20 @@ fn get_cached_status_line(status_history: &[MonitorStatus]) -> Line<'static> { } } - let spans: Vec> = status_history - .iter() - .rev() - .take(STATUS_LINE_LENGTH) - .map(|status| get_status_span(status).clone()) - .collect(); + let mut spans: Vec> = Vec::with_capacity(STATUS_LINE_LENGTH); + spans.extend( + status_history + .iter() + .rev() + .take(STATUS_LINE_LENGTH) + .map(|status| get_status_span(status).clone()), + ); let new_line = Line::from(spans); let mut write = cache.write().unwrap(); if write.len() > 1000 { - let keys_to_remove: Vec<_> = write.keys().take(250).copied().collect(); + let mut keys_to_remove: Vec = Vec::with_capacity(250); + keys_to_remove.extend(write.keys().take(250).copied()); for key in keys_to_remove { write.remove(&key); diff --git a/src/ui/dashboard/model.rs b/src/ui/dashboard/model.rs index 24dfe1f..94e1bf7 100644 --- a/src/ui/dashboard/model.rs +++ b/src/ui/dashboard/model.rs @@ -95,16 +95,12 @@ impl DashboardViewState { } fn get_status_history(heartbeats: &[HeartbeatEntry]) -> Vec { - let mut history = heartbeats - .iter() - .rev() - .take(100) - .map(|h| match h.status { - 0 => MonitorStatus::Down, - 1 => MonitorStatus::Up, - _ => MonitorStatus::Unknown, - }) - .collect::>(); + let mut history: Vec<_> = Vec::with_capacity(heartbeats.len()); + history.extend(heartbeats.iter().rev().take(100).map(|h| match h.status { + 0 => MonitorStatus::Down, + 1 => MonitorStatus::Up, + _ => MonitorStatus::Unknown, + })); while history.len() < 100 { history.push(MonitorStatus::Unknown); @@ -142,7 +138,7 @@ fn add_monitor_view_state(group: UnifiedGroupData) -> Vec { let name: Cow<'static, str> = match monitor.name { Cow::Borrowed(borrowed) => Cow::Owned(borrowed.to_string()), - Cow::Owned(owned) => Cow::Owned(owned) + Cow::Owned(owned) => Cow::Owned(owned), }; MonitorViewState {