use std::collections::VecDeque;
use std::time::Duration;
use parking_lot::Mutex;
use uuid::Uuid;
use crate::execution::planner::OperatorId;
pub const RETAINED_PROFILE_COUNT: usize = 20;
#[derive(Debug, Default)]
pub struct ProfileCollector {
profiles: Mutex<VecDeque<QueryProfile>>,
}
impl ProfileCollector {
pub fn push_profile(&self, profile: QueryProfile) {
let mut profiles = self.profiles.lock();
while profiles.len() > RETAINED_PROFILE_COUNT {
let _ = profiles.pop_back();
}
profiles.push_front(profile);
}
pub fn get_profile(&self, n: usize) -> Option<QueryProfile> {
let profiles = self.profiles.lock();
profiles.get(n).cloned()
}
pub fn get_profile_by_id(&self, id: Uuid) -> Option<QueryProfile> {
let profiles = self.profiles.lock();
profiles.iter().find(|prof| prof.id == id).cloned()
}
}
#[derive(Debug, Clone)]
pub struct QueryProfile {
pub id: Uuid,
pub plan: Option<PlanningProfile>,
pub execution: Option<ExecutionProfile>,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct OptimizerProfile {
pub total: Duration,
pub timings: Vec<(&'static str, Duration)>,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct PlanningProfile {
pub resolve_step: Option<Duration>,
pub bind_step: Option<Duration>,
pub plan_logical_step: Option<Duration>,
pub plan_optimize_step: Option<OptimizerProfile>,
pub plan_physical_step: Option<Duration>,
pub plan_executable_step: Option<Duration>,
}
#[derive(Debug, Clone)]
pub struct OperatorProfile {
pub operator_name: &'static str,
pub operator_id: OperatorId,
pub execution_duration: Duration,
pub rows_in: u64,
pub rows_out: u64,
}
#[derive(Debug, Clone)]
pub struct PartitionPipelineProfile {
pub partition_idx: usize,
pub operator_profiles: Vec<OperatorProfile>,
}
#[derive(Debug, Clone)]
pub struct ExecutionProfile {
pub partition_pipeline_profiles: Vec<PartitionPipelineProfile>,
}