Refactor cache
This commit is contained in:
parent
512f597a0f
commit
70a70af859
1 changed files with 51 additions and 15 deletions
|
|
@ -1,7 +1,10 @@
|
||||||
use std::borrow::Cow;
|
use std::{
|
||||||
use std::cmp::min;
|
borrow::Cow,
|
||||||
use std::collections::HashMap;
|
cmp::min,
|
||||||
use std::sync::OnceLock;
|
collections::{HashMap, hash_map::DefaultHasher},
|
||||||
|
hash::{Hash, Hasher},
|
||||||
|
sync::{OnceLock, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::i18n::t;
|
use crate::i18n::t;
|
||||||
use crate::ui::dashboard::{
|
use crate::ui::dashboard::{
|
||||||
|
|
@ -19,6 +22,7 @@ use ratatui::{
|
||||||
const STATUS_LINE_LENGTH: usize = 100;
|
const STATUS_LINE_LENGTH: usize = 100;
|
||||||
const MAX_NAME_LENGTH: usize = 30;
|
const MAX_NAME_LENGTH: usize = 30;
|
||||||
static STATUS_SPANS: OnceLock<HashMap<MonitorStatus, Span<'static>>> = OnceLock::new();
|
static STATUS_SPANS: OnceLock<HashMap<MonitorStatus, Span<'static>>> = OnceLock::new();
|
||||||
|
static STATUS_LINE_CACHE: OnceLock<RwLock<HashMap<u64, Vec<Span<'static>>>>> = OnceLock::new();
|
||||||
|
|
||||||
pub fn render_monitor_list(main_frame: &mut Frame, area: Rect, state: &mut DashboardViewState) {
|
pub fn render_monitor_list(main_frame: &mut Frame, area: Rect, state: &mut DashboardViewState) {
|
||||||
let available_height = area.height as usize;
|
let available_height = area.height as usize;
|
||||||
|
|
@ -185,7 +189,7 @@ fn create_monitor_item(monitor: &MonitorViewState) -> Row<'_> {
|
||||||
let response_text = format!("{:>7}ms", monitor.response_time);
|
let response_text = format!("{:>7}ms", monitor.response_time);
|
||||||
let uptime_text = format!("{:>7}%", monitor.uptime_24h);
|
let uptime_text = format!("{:>7}%", monitor.uptime_24h);
|
||||||
|
|
||||||
let status_line_spans = create_status_line_spans(&monitor.status_history);
|
let status_line_spans = get_cached_status_line(&monitor.status_history);
|
||||||
|
|
||||||
Row::new(vec![
|
Row::new(vec![
|
||||||
get_formated_line(format!("{} ", status_icon), status_color, Modifier::empty()),
|
get_formated_line(format!("{} ", status_icon), status_color, Modifier::empty()),
|
||||||
|
|
@ -225,18 +229,50 @@ fn get_cached_status_span(status: &MonitorStatus) -> Span<'static> {
|
||||||
cache.get(status).cloned().unwrap_or_default()
|
cache.get(status).cloned().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_status_line_spans(status_history: &[MonitorStatus]) -> Line<'_> {
|
|
||||||
let spans: Vec<_> = status_history
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.take(STATUS_LINE_LENGTH)
|
|
||||||
.map(|status| get_cached_status_span(status))
|
|
||||||
.collect();
|
|
||||||
Line::from(spans)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn title_style() -> Style {
|
fn title_style() -> Style {
|
||||||
Style::default()
|
Style::default()
|
||||||
.fg(Color::Yellow)
|
.fg(Color::Yellow)
|
||||||
.add_modifier(Modifier::BOLD)
|
.add_modifier(Modifier::BOLD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calculate_history_hash(status_history: &[MonitorStatus]) -> u64 {
|
||||||
|
let mut hasher = DefaultHasher::new();
|
||||||
|
status_history
|
||||||
|
.iter()
|
||||||
|
.take(STATUS_LINE_LENGTH)
|
||||||
|
.for_each(|status| {
|
||||||
|
status.hash(&mut hasher);
|
||||||
|
});
|
||||||
|
hasher.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cached_status_line(status_history: &[MonitorStatus]) -> Line<'static> {
|
||||||
|
let hash = calculate_history_hash(status_history);
|
||||||
|
let cache = STATUS_LINE_CACHE.get_or_init(|| RwLock::new(HashMap::new()));
|
||||||
|
{
|
||||||
|
let read = cache.read().unwrap();
|
||||||
|
if let Some(spans) = read.get(&hash) {
|
||||||
|
return Line::from(spans.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let spans: Vec<Span<'static>> = status_history
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.take(STATUS_LINE_LENGTH)
|
||||||
|
.map(|status| get_cached_status_span(status))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut write = cache.write().unwrap();
|
||||||
|
if write.len() > 1000 {
|
||||||
|
|
||||||
|
let keys_to_remove: Vec<_> = write.keys().take(250).copied().collect();
|
||||||
|
|
||||||
|
for key in keys_to_remove {
|
||||||
|
write.remove(&key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
write.insert(hash, spans.clone());
|
||||||
|
Line::from(spans)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue