use std::cell::RefCell;
use std::collections::HashMap;
use ratatui::text::Line;
use crate::tui::chat::message::ChatMessage;
use crate::tui::message_formatter::MessageFormatter;
type Key = (u128, usize, usize, u8);
const CACHE_CAP: usize = 512;
thread_local! {
static FORMAT_CACHE: RefCell<HashMap<Key, Vec<Line<'static>>>> =
RefCell::new(HashMap::with_capacity(128));
}
fn role_discrim(r: &str) -> u8 {
match r {
"user" => 1,
"assistant" => 2,
"system" => 3,
"error" => 4,
_ => 0,
}
}
fn ts_nanos(m: &ChatMessage) -> u128 {
m.timestamp
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_nanos())
.unwrap_or(0)
}
pub fn format_message_cached(
message: &ChatMessage,
role: &str,
formatter: &MessageFormatter,
max_width: usize,
) -> Vec<Line<'static>> {
let key = (
ts_nanos(message),
message.content.len(),
max_width,
role_discrim(role),
);
FORMAT_CACHE.with(|c| {
if let Some(l) = c.borrow().get(&key) {
return l.clone();
}
let lines = formatter.format_content(&message.content, role);
let mut m = c.borrow_mut();
if m.len() >= CACHE_CAP {
m.clear();
}
m.insert(key, lines.clone());
lines
})
}
pub fn reset_format_cache() {
FORMAT_CACHE.with(|c| c.borrow_mut().clear());
}