diff --git a/src/runtime2/consensus.rs b/src/runtime2/consensus.rs index 49cdab9fdcf2c70ea447a59b5699f7b1829d5b99..414eb41e010fd994845247ae6e8ce0fdeaee387a 100644 --- a/src/runtime2/consensus.rs +++ b/src/runtime2/consensus.rs @@ -19,9 +19,9 @@ pub(crate) struct LocalSolution { port_mapping: Vec<(PortIdLocal, BranchId)>, } -pub(crate) struct GlobalSolution { - -} +// ----------------------------------------------------------------------------- +// Consensus +// ----------------------------------------------------------------------------- /// The consensus algorithm. Currently only implemented to find the component /// with the highest ID within the sync region and letting it handle all the @@ -274,7 +274,7 @@ impl Consensus { } // But also send our locally combined solution - self.forward_local_solutions(); + self.forward_local_solutions(ctx); } else if sync_header.highest_component_id < self.highest_connector_id { // Sender has lower leader ID, so it should know about our higher // one. @@ -400,6 +400,80 @@ impl Consensus { } } +// ----------------------------------------------------------------------------- +// Solution storage and algorithms +// ----------------------------------------------------------------------------- + +struct MatchedLocalSolution { + final_branch_id: BranchId, + port_mapping: Vec<(PortIdLocal, BranchId)>, + matches: Vec, +} + +struct ComponentMatches { + target_id: ConnectorId, + target_index: usize, + match_indices: Vec, + involved_ports: Vec, +} + +struct ComponentLocalSolutions { + component: ConnectorId, + solutions: Vec, +} + +// TODO: Flatten? Flatten. Flatten everything. +pub(crate) struct GlobalSolution { + local: Vec +} + +impl GlobalSolution { + fn new() -> Self { + return Self{ + local: Vec::new(), + }; + } + + fn add_solution(&mut self, solution: LocalSolution) { + let component_id = solution.component; + let solution = MatchedLocalSolution{ + final_branch_id: solution.final_branch_id, + port_mapping: solution.port_mapping, + matches: Vec::new(), + }; + + // Create an entry for the solution for the particular component + let component_exists = self.local.iter_mut() + .enumerate() + .find(|(_, v)| v.component == component_id); + let (component_index, solution_index) = match component_exists { + Some((component_index, storage)) => { + // Entry for component exists, so add to solutions + let solution_index = storage.solutions.len(); + storage.solutions.push(solution); + + (component_index, solution_index) + } + None => { + // Entry for component does not exist yet + let component_index = self.local.len(); + self.local.push(ComponentLocalSolutions{ + component: component_id, + solutions: vec![solution], + }); + (component_index, 0) + } + }; + + // Compare this new solution to other solutions of different components + // to see if we get a closed global solution. + } +} + +// ----------------------------------------------------------------------------- +// Generic Helpers +// ----------------------------------------------------------------------------- + /// Recursively goes through the value group, attempting to find ports. /// Duplicates will only be added once. pub(crate) fn find_ports_in_value_group(value_group: &ValueGroup, ports: &mut Vec) {