-
-
Save jameshanlon/a14685408f8b0f44919610d7f7cfa4a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::BinaryHeap; | |
use std::vec::Vec; | |
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] | |
enum EventType { | |
Transmit, | |
Receive, | |
} | |
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] | |
struct Event { | |
event_type: EventType, | |
time: usize, | |
node_id: usize, | |
} | |
struct Node { | |
active: bool | |
} | |
impl Node { | |
fn new() -> Self { | |
Node { | |
active: false, | |
} | |
} | |
} | |
struct State { | |
nodes: Vec<Node> | |
} | |
impl State { | |
fn new() -> Self { | |
State { | |
nodes: Vec::new(), | |
} | |
} | |
fn add_node(&mut self) { | |
self.nodes.push(Node::new()); | |
} | |
fn next_node(&self, id: usize) -> usize { | |
(id + 1).rem_euclid(self.nodes.len()) | |
} | |
} | |
const TIME_STEP : usize = 2; | |
struct Simulator { | |
max_cycles: usize, | |
current_time: usize, | |
event_queue: BinaryHeap<Event>, | |
state: State, | |
} | |
impl Simulator { | |
fn new(max_cycles: usize) -> Self { | |
Simulator { | |
max_cycles: max_cycles, | |
current_time: 0, | |
event_queue: BinaryHeap::new(), | |
state: State::new(), | |
} | |
} | |
fn schedule_event(&mut self, event: Event) { | |
self.event_queue.push(event); | |
} | |
fn run(&mut self) { | |
while let Some(event) = self.event_queue.pop() { | |
if self.max_cycles > 0 && self.current_time >= self.max_cycles { | |
break; | |
} | |
self.current_time = event.time; | |
self.handle_event(event); | |
} | |
} | |
fn next_timestep(&self, time: usize) -> usize { | |
((time + TIME_STEP) / TIME_STEP) * TIME_STEP | |
} | |
fn handle_event(&mut self, event: Event) { | |
match event.event_type { | |
EventType::Transmit => { | |
// Deactivate. | |
self.state.nodes[event.node_id].active = false; | |
println!("Node {} inactive", event.node_id); | |
// Schedule receive at next node. | |
let recv_event = Event { | |
event_type: EventType::Receive, | |
time: self.current_time + 1, | |
node_id: self.state.next_node(event.node_id), | |
}; | |
self.schedule_event(recv_event); | |
} | |
EventType::Receive => { | |
// Activate. | |
self.state.nodes[event.node_id].active = true; | |
println!("Node {} active", event.node_id); | |
// Schedule transmit. | |
let send_event = Event { | |
event_type: EventType::Transmit, | |
time: self.next_timestep(self.current_time), | |
node_id: event.node_id, | |
}; | |
self.schedule_event(send_event); | |
} | |
} | |
} | |
} | |
fn main() { | |
let mut sim = Simulator::new(20); | |
for _ in 0..10 { | |
sim.state.add_node(); | |
} | |
let initial_event = Event { event_type: EventType::Receive, time: 0, node_id: 0 }; | |
sim.schedule_event(initial_event); | |
sim.run(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment