use alloc::{
collections::VecDeque,
string::{String, ToString},
vec::Vec,
};
use core::time::Duration;
use hashbrown::HashMap;
pub use crate::monitors::stats::{
ClientStats, EdgeCoverage, ItemGeometry, ProcessTiming, TimedStat, TimedStats, UserStatsTag,
user_stats::{TAG_AFL_STATS_CYCLES_DONE, UserStats},
};
pub const DEFAULT_TIME_WINDOW: u64 = 60 * 10; const DEFAULT_LOGS_NUMBER: usize = 128;
pub const DEFAULT_CHARTS: &[&str] = &["corpus", "objectives", "exec/sec"];
#[derive(Debug, Default, Clone)]
pub struct ClientTuiContext {
pub client_stats: ClientStats,
pub process_timing: ProcessTiming,
pub item_geometry: Option<ItemGeometry>,
}
impl ClientTuiContext {
pub fn grab_data(&mut self, client: &mut ClientStats) {
self.process_timing = client.process_timing();
self.item_geometry = client.item_geometry();
self.client_stats = client.clone();
}
#[must_use]
pub fn cycles_done(&self) -> Option<u64> {
self.client_stats
.user_stats_by_tag(TAG_AFL_STATS_CYCLES_DONE)
.next()
.and_then(|s: &UserStats| s.value().as_u64())
}
#[must_use]
pub fn executions(&self) -> u64 {
self.client_stats.executions()
}
#[must_use]
pub fn corpus(&self) -> u64 {
self.client_stats.corpus_size()
}
#[must_use]
pub fn objectives(&self) -> u64 {
self.client_stats.objective_size()
}
}
#[derive(Debug, Clone)]
pub struct TuiContext {
pub graphs: Vec<String>,
pub(crate) tags: HashMap<String, UserStatsTag>,
pub corpus_size_timed: TimedStats,
pub objective_size_timed: TimedStats,
pub execs_per_sec_timed: TimedStats,
pub custom_timed: HashMap<String, TimedStats>,
pub clients: HashMap<usize, ClientTuiContext>,
pub client_logs: VecDeque<String>,
pub clients_num: usize,
pub total_execs: u64,
pub start_time: Duration,
pub total_map_density: String,
pub total_solutions: u64,
pub total_corpus_count: u64,
pub total_item_geometry: Option<ItemGeometry>,
pub total_process_timing: ProcessTiming,
}
impl TuiContext {
#[must_use]
pub fn new(start_time: Duration) -> Self {
Self {
start_time,
clients: HashMap::default(),
client_logs: VecDeque::with_capacity(DEFAULT_LOGS_NUMBER),
total_execs: 0,
clients_num: 0,
total_map_density: String::new(),
total_solutions: 0,
total_corpus_count: 0,
total_item_geometry: None,
total_process_timing: ProcessTiming::new(),
graphs: DEFAULT_CHARTS.iter().map(ToString::to_string).collect(),
tags: HashMap::default(),
corpus_size_timed: TimedStats::new(Duration::from_secs(DEFAULT_TIME_WINDOW)),
objective_size_timed: TimedStats::new(Duration::from_secs(DEFAULT_TIME_WINDOW)),
execs_per_sec_timed: TimedStats::new(Duration::from_secs(DEFAULT_TIME_WINDOW)),
custom_timed: HashMap::default(),
}
}
}