use crate::protocol::eval::*; use super::runtime::*; use super::component::*; // ----------------------------------------------------------------------------- // Generic types // ----------------------------------------------------------------------------- #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct PortId(pub u32); impl PortId { /// This value is not significant, it is chosen to make debugging easier: a /// very large port number is more likely to shine a light on bugs. pub fn new_invalid() -> Self { return Self(u32::MAX); } } pub struct Peer { pub id: CompId, pub num_associated_ports: u32, pub(crate) handle: CompHandle, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum PortKind { Putter, Getter, } #[derive(Debug, PartialEq, Eq)] pub enum PortState { Open, Blocked, Closed, } pub struct Port { pub self_id: PortId, pub peer_id: PortId, pub kind: PortKind, pub state: PortState, pub peer_comp_id: CompId, } pub struct Channel { pub putter_id: PortId, pub getter_id: PortId, } // ----------------------------------------------------------------------------- // Data messages // ----------------------------------------------------------------------------- #[derive(Debug)] pub struct DataMessage { pub data_header: MessageDataHeader, pub sync_header: MessageSyncHeader, pub content: ValueGroup, } #[derive(Debug)] pub struct MessageDataHeader { pub expected_mapping: Vec<(PortId, Option)>, pub new_mapping: u32, pub source_port: PortId, pub target_port: PortId, } // ----------------------------------------------------------------------------- // Sync messages // ----------------------------------------------------------------------------- #[derive(Debug)] pub struct SyncMessage { pub sync_header: MessageSyncHeader, pub content: SyncMessageContent, } pub struct SyncLocalSolutionEntry { pub self_port_id: PortId, pub peer_comp_id: CompId, pub peer_port_id: PortId, pub mapping: u32, pub port_kind: PortKind, } pub type SyncLocalSolution = Vec; pub struct SyncSolutionPort { pub self_comp_id: CompId, pub self_port_id: PortId, pub peer_comp_id: CompId, pub peer_port_id: PortId, pub mapping: u32, pub port_kind: PortKind, } pub struct SyncSolutionChannel { pub putter: Option, pub getter: Option, } #[derive(Copy, Clone)] pub enum RoundDecision { None, Solution, Failure, } impl RoundDecision { fn is_some(&self) } pub struct SyncPartialSolution { pub submissions_by: Vec<(CompId, bool)>, pub channel_mapping: Vec, pub decision: SyncRoundDecision, } #[derive(Debug, Clone)] pub enum SyncMessageContent { NotificationOfLeader, LocalSolution(CompId, SyncLocalSolution), // local solution of the specified component PartialSolution(SyncPartialSolution), // partial solution of multiple components GlobalSolution, GlobalFailure, } // ----------------------------------------------------------------------------- // Control messages // ----------------------------------------------------------------------------- #[derive(Debug)] pub struct ControlMessage { pub(crate) id: ControlId, pub sender_comp_id: CompId, pub target_port_id: Option, pub content: ControlMessageContent, } #[derive(Copy, Clone, Debug)] pub enum ControlMessageContent { Ack, BlockPort(PortId), UnblockPort(PortId), ClosePort(PortId), PortPeerChangedBlock(PortId), PortPeerChangedUnblock(PortId, CompId), } // ----------------------------------------------------------------------------- // Messages (generic) // ----------------------------------------------------------------------------- #[derive(Debug)] pub struct MessageSyncHeader { pub sync_round: u32, pub sending_id: CompId, pub highest_id: CompId, } #[derive(Debug)] pub enum Message { Data(DataMessage), Sync(SyncMessage), Control(ControlMessage), } impl Message { pub(crate) fn target_port(&self) -> Option { match self { Message::Data(v) => return Some(v.data_header.target_port), Message::Control(v) => return v.target_port_id, Message::Sync(_) => return None, } } }