use crate::{
ospf::OspfProcess,
router::Router,
types::{PhysicalNetwork, Prefix, RouterId},
};
use ordered_float::NotNan;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, VecDeque};
use super::Event;
pub trait EventQueue<P: Prefix> {
type Priority: Default + FmtPriority + Clone;
fn push<Ospf: OspfProcess>(
&mut self,
event: Event<P, Self::Priority>,
routers: &BTreeMap<RouterId, Router<P, Ospf>>,
net: &PhysicalNetwork,
);
fn push_many<Ospf: OspfProcess>(
&mut self,
events: Vec<Event<P, Self::Priority>>,
routers: &BTreeMap<RouterId, Router<P, Ospf>>,
net: &PhysicalNetwork,
) {
events.into_iter().for_each(|e| self.push(e, routers, net))
}
fn pop(&mut self) -> Option<Event<P, Self::Priority>>;
fn peek(&self) -> Option<&Event<P, Self::Priority>>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.peek().is_none()
}
fn clear(&mut self);
fn update_params<Ospf: OspfProcess>(
&mut self,
routers: &BTreeMap<RouterId, Router<P, Ospf>>,
net: &PhysicalNetwork,
);
fn get_time(&self) -> Option<f64>;
unsafe fn clone_events(&self, conquered: Self) -> Self;
}
pub trait ConcurrentEventQueue<P: Prefix>: EventQueue<P> {
fn pop_events_for(&mut self, destination: RouterId) -> Vec<Event<P, Self::Priority>>;
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(bound(deserialize = "P: for<'a> serde::Deserialize<'a>"))]
pub struct BasicEventQueue<P: Prefix>(pub(crate) VecDeque<Event<P, ()>>);
impl<P: Prefix> Default for BasicEventQueue<P> {
fn default() -> Self {
Self(Default::default())
}
}
impl<P: Prefix> BasicEventQueue<P> {
pub fn new() -> Self {
Self(VecDeque::new())
}
}
impl<P: Prefix> EventQueue<P> for BasicEventQueue<P> {
type Priority = ();
fn push<Ospf: OspfProcess>(
&mut self,
event: Event<P, Self::Priority>,
_: &BTreeMap<RouterId, Router<P, Ospf>>,
_: &PhysicalNetwork,
) {
self.0.push_back(event)
}
fn pop(&mut self) -> Option<Event<P, Self::Priority>> {
self.0.pop_front()
}
fn peek(&self) -> Option<&Event<P, Self::Priority>> {
self.0.front()
}
fn len(&self) -> usize {
self.0.len()
}
fn is_empty(&self) -> bool {
self.0.is_empty()
}
fn clear(&mut self) {
self.0.clear()
}
fn get_time(&self) -> Option<f64> {
None
}
fn update_params<Ospf: OspfProcess>(
&mut self,
_: &BTreeMap<RouterId, Router<P, Ospf>>,
_: &PhysicalNetwork,
) {
}
unsafe fn clone_events(&self, _: Self) -> Self {
self.clone()
}
}
pub trait FmtPriority {
fn fmt(&self) -> String;
}
impl FmtPriority for f64 {
fn fmt(&self) -> String {
format!("(time: {self})")
}
}
impl FmtPriority for NotNan<f64> {
fn fmt(&self) -> String {
format!("(time: {})", self.into_inner())
}
}
impl FmtPriority for usize {
fn fmt(&self) -> String {
format!("(priority: {self})")
}
}
impl FmtPriority for () {
fn fmt(&self) -> String {
String::new()
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(bound(deserialize = "P: for<'a> serde::Deserialize<'a>"))]
pub struct PerRouterQueue<P: Prefix> {
pub(crate) events: BTreeMap<RouterId, VecDeque<Event<P, ()>>>,
pub(crate) num_events: usize,
}
impl<P: Prefix> Default for PerRouterQueue<P> {
fn default() -> Self {
Self {
events: BTreeMap::new(),
num_events: 0,
}
}
}
impl<P: Prefix> EventQueue<P> for PerRouterQueue<P> {
type Priority = ();
fn push<Ospf: OspfProcess>(
&mut self,
event: Event<P, Self::Priority>,
_routers: &BTreeMap<RouterId, Router<P, Ospf>>,
_net: &PhysicalNetwork,
) {
self.events
.entry(event.router())
.or_default()
.push_back(event);
self.num_events += 1
}
fn pop(&mut self) -> Option<Event<P, Self::Priority>> {
let mut e = self.events.first_entry()?;
let ev = e.get_mut().pop_front().unwrap();
if e.get().is_empty() {
e.remove_entry();
}
self.num_events -= 1;
Some(ev)
}
fn peek(&self) -> Option<&Event<P, Self::Priority>> {
Some(self.events.first_key_value()?.1.front().unwrap())
}
fn len(&self) -> usize {
self.num_events
}
fn is_empty(&self) -> bool {
self.num_events == 0
}
fn clear(&mut self) {
self.events.clear();
self.num_events = 0;
}
fn update_params<Ospf: OspfProcess>(
&mut self,
_routers: &BTreeMap<RouterId, Router<P, Ospf>>,
_net: &PhysicalNetwork,
) {
}
fn get_time(&self) -> Option<f64> {
None
}
unsafe fn clone_events(&self, _conquered: Self) -> Self {
self.clone()
}
}
impl<P: Prefix> ConcurrentEventQueue<P> for PerRouterQueue<P> {
fn pop_events_for(&mut self, destination: RouterId) -> Vec<Event<P, Self::Priority>> {
let Some(e) = self.events.remove(&destination) else {
return Vec::new();
};
self.num_events -= e.len();
e.into()
}
}