use std::collections::HashMap;
use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::network::Coord;
use crate::scheduler::BlockId;
pub type TimePoint = u32;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ProfilerResult {
pub thread_name: String,
pub buckets: Vec<ProfilerBucket>,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct ProfilerMetrics {
#[serde(serialize_with = "serialize_map", deserialize_with = "deserialize_map")]
pub items_in: HashMap<(Coord, Coord), usize>,
#[serde(serialize_with = "serialize_map", deserialize_with = "deserialize_map")]
pub items_out: HashMap<(Coord, Coord), usize>,
#[serde(serialize_with = "serialize_map", deserialize_with = "deserialize_map")]
pub net_messages_in: HashMap<(Coord, Coord), (usize, usize)>,
#[serde(serialize_with = "serialize_map", deserialize_with = "deserialize_map")]
pub net_messages_out: HashMap<(Coord, Coord), (usize, usize)>,
pub iteration_boundaries: Vec<(BlockId, TimePoint)>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ProfilerBucket {
pub start_ms: TimePoint,
pub metrics: ProfilerMetrics,
}
impl ProfilerBucket {
#[inline]
#[allow(dead_code)]
pub fn new(start_ms: TimePoint) -> Self {
Self {
start_ms,
metrics: Default::default(),
}
}
}
#[derive(Serialize, Deserialize)]
struct Entry<T> {
from: Coord,
to: Coord,
value: T,
}
fn serialize_map<S: Serializer, T: Serialize + Copy>(
map: &HashMap<(Coord, Coord), T>,
s: S,
) -> Result<S::Ok, S::Error> {
let mut seq = s.serialize_seq(Some(map.len()))?;
for (&(from, to), &value) in map.iter() {
let entry = Entry { from, to, value };
seq.serialize_element(&entry)?;
}
seq.end()
}
fn deserialize_map<'de, D, T>(d: D) -> Result<HashMap<(Coord, Coord), T>, D::Error>
where
D: Deserializer<'de>,
T: Deserialize<'de>,
{
let as_vec: Vec<Entry<T>> = serde::de::Deserialize::deserialize(d)?;
Ok(as_vec
.into_iter()
.map(|e| ((e.from, e.to), e.value))
.collect())
}