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>,
}
impl NodeProfile {
fn update_id(&mut self, new_id: usize) {
self.id = new_id;
}
fn update_name(&mut self, new_name: String) {
self.name = new_name;
}
fn update_block(&mut self, new_block: String) {
self.block = new_block;
}
fn update_fingerprint(&mut self, fingerprint: u64) {
self.fingerprint = Some(format!("0x{:016x}", fingerprint));
}
fn add_tag(&mut self, tag: String) {
self.tags.push(tag);
}
fn add_operators(&mut self, operator_addrs: Vec<Addr>) {
self.operators.extend(operator_addrs);
}
fn add_parents(&mut self, parent_ids: Vec<usize>) {
self.parents.extend(parent_ids);
}
}
#[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 mut node = NodeProfile::default();
let parent_ids = input_variable_names
.iter()
.filter_map(|variable_name| self.node_map.get(variable_name).copied())
.collect();
node.update_id(self.id_cnt);
node.update_name(name);
node.update_block(self.block.clone());
if let Some(fingerprint) = fingerprint {
node.update_fingerprint(fingerprint);
}
node.add_tag(tag.to_string());
node.add_operators(self.addr_cnt.advance(operator_steps));
node.add_parents(parent_ids);
if let Some(output_variable_name) = output_variable_name {
self.node_map.insert(output_variable_name, self.id_cnt);
}
self.id_cnt += 1;
node
}
}