use fountain_engine::types::Operation;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct PerformanceMetrics {
pub multiply_alpha: usize,
pub multiply_scalar: usize,
pub vector_add: usize,
pub mul_add: usize,
pub max_storage: usize,
pub num_coded_vectors: usize,
}
impl PerformanceMetrics {
pub fn from_operations(operations: &[Operation], coded_vector_inserted: usize) -> Self {
let mut metrics = Self::default();
let mut current_storage = coded_vector_inserted;
for operation in operations {
match operation {
Operation::EnsureZero { list_id } => {
current_storage += list_id.len();
if current_storage > metrics.max_storage {
metrics.max_storage = current_storage;
}
}
Operation::EnsureZeroOne { .. } => {
current_storage += 1;
if current_storage > metrics.max_storage {
metrics.max_storage = current_storage;
}
}
Operation::MultiplyAlpha { .. } => metrics.multiply_alpha += 1,
Operation::MultiplyScalar { .. } => metrics.multiply_scalar += 1,
Operation::AddOneToVector { .. } => metrics.vector_add += 1,
Operation::AddTwoToVector { .. } => metrics.vector_add += 2,
Operation::AddThreeToVector { .. } => metrics.vector_add += 3,
Operation::AddToVector { list_id, .. } => metrics.vector_add += list_id.len(),
Operation::BroadcastAdd { target_ids, .. } => {
metrics.vector_add += target_ids.len()
}
Operation::MulAdd { .. } => metrics.mul_add += 1,
Operation::MoveTo { .. } => {}
Operation::CopyTo { .. } => {
current_storage += 1;
if current_storage > metrics.max_storage {
metrics.max_storage = current_storage;
}
}
Operation::Remove { .. } => {
if let Some(new_value) = current_storage.checked_sub(1) {
current_storage = new_value;
} else {
panic!("Current storage is 0, cannot remove a vector");
}
}
Operation::InfoCodedVector { .. } => metrics.num_coded_vectors += 1,
}
}
metrics
}
}