Skip to content

Instantly share code, notes, and snippets.

@jameshanlon
Created August 11, 2024 20:06
Show Gist options
  • Save jameshanlon/a14685408f8b0f44919610d7f7cfa4a6 to your computer and use it in GitHub Desktop.
Save jameshanlon/a14685408f8b0f44919610d7f7cfa4a6 to your computer and use it in GitHub Desktop.
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