use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::profiler::addr::Addr;
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub(super) struct NodeProfile {
id: usize,
name: String,
block: String,
fingerprint: Option<String>,
tags: Vec<String>,
operators: Vec<Addr>,
parents: Vec<usize>,
}
#[derive(Debug, Clone, Default)]
pub(super) struct NodeManager {
id_cnt: usize,
addr_cnt: Addr,
block: String,
node_map: HashMap<String, usize>,
}
impl NodeManager {
pub(super) fn update_input_block(&mut self) {
self.block = "input".to_string();
}
pub(super) fn update_stratum_block(&mut self, stratum_id: usize) {
self.block = format!("stratum {}", stratum_id);
}
pub(super) fn update_inspect_block(&mut self) {
self.block = "inspect".to_string();
}
pub(super) fn enter_scope(&mut self) {
self.addr_cnt.enter_scope();
}
pub(super) fn leave_scope(&mut self) {
self.addr_cnt.leave_scope();
self.addr_cnt.advance(1);
}
pub(super) fn build_node(
&mut self,
name: String,
input_variable_names: Vec<String>,
output_variable_name: Option<String>,
tag: &str,
operator_steps: u32,
fingerprint: Option<u64>,
) -> NodeProfile {
let parents = input_variable_names
.iter()
.filter_map(|variable_name| self.node_map.get(variable_name).copied())
.collect();
let node = NodeProfile {
id: self.id_cnt,
name,
block: self.block.clone(),
fingerprint: fingerprint.map(|fp| format!("0x{:016x}", fp)),
tags: vec![tag.to_string()],
operators: self.addr_cnt.advance(operator_steps),
parents,
};
if let Some(output_variable_name) = output_variable_name {
self.node_map.insert(output_variable_name, self.id_cnt);
}
self.id_cnt += 1;
node
}
}