use hopr_types::internal::routing::PathId;
use super::{MeasurablePath, MeasurablePeer};
use crate::graph::{MeasurableEdge, MeasurableNode};
pub type EdgeTransportMeasurement = std::result::Result<std::time::Duration, ()>;
pub type Capacity = u128;
#[derive(Debug)]
pub enum EdgeWeightType {
Immediate(EdgeTransportMeasurement),
Intermediate(EdgeTransportMeasurement),
Capacity(Option<Capacity>),
Connected(bool),
ImmediateProtocolConformance {
num_packets: u64,
num_acks: u64,
},
}
pub trait EdgeObservableWrite {
fn record(&mut self, measurement: EdgeWeightType);
}
pub trait EdgeNetworkObservableRead {
fn is_connected(&self) -> bool;
}
pub trait EdgeProtocolObservable {
fn capacity(&self) -> Option<u128>;
}
pub trait EdgeImmediateProtocolObservable {
fn ack_rate(&self) -> Option<f64>;
}
pub trait EdgeObservableRead {
type ImmediateMeasurement: EdgeLinkObservable + EdgeNetworkObservableRead + EdgeImmediateProtocolObservable + Send;
type IntermediateMeasurement: EdgeLinkObservable + EdgeProtocolObservable + Send;
fn last_update(&self) -> std::time::Duration;
fn immediate_qos(&self) -> Option<&Self::ImmediateMeasurement>;
fn intermediate_qos(&self) -> Option<&Self::IntermediateMeasurement>;
fn score(&self) -> f64;
}
pub trait EdgeObservable: EdgeObservableRead + EdgeObservableWrite {}
impl<T: EdgeObservableWrite + EdgeObservableRead> EdgeObservable for T {}
pub trait EdgeLinkObservable {
fn record(&mut self, measurement: EdgeTransportMeasurement);
fn average_latency(&self) -> Option<std::time::Duration>;
fn average_probe_rate(&self) -> f64;
fn score(&self) -> f64;
}
#[derive(Debug, Clone)]
pub enum NodeObservation<T> {
Discovered(T),
Connected(T),
Disconnected(T),
}
pub trait NodeObservable {
type Node: MeasurablePeer + Send;
fn record_node(&mut self, observation: NodeObservation<Self::Node>);
}
#[auto_impl::auto_impl(&, Box, Arc)]
pub trait NetworkGraphView {
type Observed: EdgeObservable + Send;
type NodeId: Send;
fn node_count(&self) -> usize;
fn contains_node(&self, key: &Self::NodeId) -> bool;
fn nodes(&self) -> futures::stream::BoxStream<'static, Self::NodeId>;
fn has_edge(&self, src: &Self::NodeId, dest: &Self::NodeId) -> bool {
self.edge(src, dest).is_some()
}
fn edge(&self, src: &Self::NodeId, dest: &Self::NodeId) -> Option<Self::Observed>;
fn identity(&self) -> &Self::NodeId;
}
#[auto_impl::auto_impl(&, Box, Arc)]
pub trait NetworkGraphWrite {
type Error;
type Observed: EdgeObservable + Send;
type NodeId: Send;
fn add_node(&self, key: Self::NodeId);
fn remove_node(&self, key: &Self::NodeId);
fn add_edge(&self, src: &Self::NodeId, dest: &Self::NodeId) -> Result<(), Self::Error>;
fn remove_edge(&self, src: &Self::NodeId, dest: &Self::NodeId);
fn upsert_edge<F>(&self, src: &Self::NodeId, dest: &Self::NodeId, f: F)
where
F: FnOnce(&mut Self::Observed);
}
#[auto_impl::auto_impl(&, Box, Arc)]
pub trait NetworkGraphUpdate {
fn record_edge<N, P>(&self, update: MeasurableEdge<N, P>)
where
N: MeasurablePeer + Clone + Send + Sync + 'static,
P: MeasurablePath + Clone + Send + Sync + 'static;
fn record_node<N>(&self, update: N)
where
N: MeasurableNode + Clone + Send + Sync + 'static;
}
#[allow(clippy::type_complexity)]
pub trait ValueFn {
type Weight: EdgeObservableRead + Send;
type Value: Clone + PartialOrd + Send + Sync;
fn initial_value(&self) -> Self::Value;
fn min_value(&self) -> Option<Self::Value>;
fn into_value_fn(self) -> std::sync::Arc<dyn Fn(Self::Value, &Self::Weight, usize) -> Self::Value + Send + Sync>;
}
#[auto_impl::auto_impl(&, Box, Arc)]
pub trait NetworkGraphTraverse {
type NodeId: Send + Sync;
type Observed: EdgeObservableRead + Send;
fn simple_paths<V: ValueFn<Weight = Self::Observed>>(
&self,
source: &Self::NodeId,
destination: &Self::NodeId,
length: usize,
take_count: Option<usize>,
value_fn: V,
) -> Vec<(Vec<Self::NodeId>, PathId, V::Value)>;
fn simple_paths_from<V: ValueFn<Weight = Self::Observed>>(
&self,
source: &Self::NodeId,
length: usize,
take_count: Option<usize>,
value_fn: V,
) -> Vec<(Vec<Self::NodeId>, PathId, V::Value)>;
fn simple_loopback_to_self(&self, length: usize, take_count: Option<usize>) -> Vec<(Vec<Self::NodeId>, PathId)>;
}
#[auto_impl::auto_impl(&, Box, Arc)]
pub trait NetworkGraphConnectivity {
type NodeId: Send + Sync;
type Observed: EdgeObservableRead + Send;
fn connected_edges(&self) -> Vec<(Self::NodeId, Self::NodeId, Self::Observed)>;
fn reachable_edges(&self) -> Vec<(Self::NodeId, Self::NodeId, Self::Observed)>;
}