use crate::{
BusDeviceMetrics, CheckPoint, ChunkId, InstCount, InstanceType, Metrics, Plan, Planner,
RegularCounters,
};
use zisk_core::ZiskOperationType;
use super::plan;
#[derive(Debug)]
pub struct InstanceInfo {
pub airgroup_id: usize,
pub air_id: usize,
pub num_ops: usize,
pub op_type: ZiskOperationType,
}
impl InstanceInfo {
pub fn new(
airgroup_id: usize,
air_id: usize,
num_ops: usize,
op_type: ZiskOperationType,
) -> Self {
InstanceInfo { air_id, airgroup_id, num_ops, op_type }
}
}
pub struct TableInfo {
pub airgroup_id: usize,
pub air_id: usize,
}
impl TableInfo {
pub fn new(airgroup_id: usize, air_id: usize) -> Self {
TableInfo { air_id, airgroup_id }
}
}
#[derive(Default)]
pub struct RegularPlanner {
instances_info: Vec<InstanceInfo>,
tables_info: Vec<TableInfo>,
}
impl RegularPlanner {
pub fn new() -> Self {
Self { instances_info: Vec::new(), tables_info: Vec::new() }
}
pub fn add_instance(mut self, instance_info: InstanceInfo) -> Self {
self.instances_info.push(instance_info);
self
}
pub fn add_table_instance(mut self, table_info: TableInfo) -> Self {
self.tables_info.push(table_info);
self
}
}
impl Planner for RegularPlanner {
fn plan(&self, counters: Vec<(ChunkId, Box<dyn BusDeviceMetrics>)>) -> Vec<Plan> {
let mut count: Vec<Vec<InstCount>> = Vec::with_capacity(self.instances_info.len());
for _ in 0..self.instances_info.len() {
count.push(Vec::new());
}
counters.iter().for_each(|(chunk_id, counter)| {
let reg_counter =
Metrics::as_any(&**counter).downcast_ref::<RegularCounters>().unwrap();
for (index, instance_info) in self.instances_info.iter().enumerate() {
let inst_count = InstCount::new(
*chunk_id,
reg_counter.inst_count(instance_info.op_type).unwrap(),
);
count[index].push(inst_count);
}
});
let mut plan_result = Vec::new();
for (idx, instance) in self.instances_info.iter().enumerate() {
let plan: Vec<_> = plan(&count[idx], instance.num_ops as u64)
.into_iter()
.map(|(check_point, collect_info)| {
let converted = Box::new(collect_info);
Plan::new(
instance.airgroup_id,
instance.air_id,
None,
InstanceType::Instance,
check_point,
Some(converted),
)
})
.collect();
plan_result.extend(plan);
}
if !plan_result.is_empty() {
for table_instance in self.tables_info.iter() {
plan_result.push(Plan::new(
table_instance.airgroup_id,
table_instance.air_id,
None,
InstanceType::Table,
CheckPoint::None,
None,
));
}
}
plan_result
}
}