docs: bilingual comments for mesh and routing
This commit is contained in:
parent
c442acc6e5
commit
5857c44492
|
|
@ -4,20 +4,32 @@ use crate::connectivity::{edge_connectivity, reachable_from, strongly_connected_
|
|||
use apsis_topology::Topology;
|
||||
|
||||
/// A link whose removal would change the connectivity of the mesh.
|
||||
///
|
||||
/// 一条移除后会改变网格连通性的链路。
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct CriticalLink {
|
||||
/// The node the link leaves.
|
||||
///
|
||||
/// 该链路离开的节点。
|
||||
pub from: usize,
|
||||
/// The node the link arrives at.
|
||||
///
|
||||
/// 该链路到达的节点。
|
||||
pub to: usize,
|
||||
/// The cost of the link.
|
||||
///
|
||||
/// 该链路的代价。
|
||||
pub cost: f64,
|
||||
/// The number of components the mesh has after the link is removed.
|
||||
///
|
||||
/// 移除该链路后网格所具有的分量数。
|
||||
pub components_without: usize,
|
||||
}
|
||||
|
||||
impl CriticalLink {
|
||||
/// Creates a critical link record.
|
||||
///
|
||||
/// 创建关键链路记录。
|
||||
pub const fn new(from: usize, to: usize, cost: f64, components_without: usize) -> Self {
|
||||
Self {
|
||||
from,
|
||||
|
|
@ -29,15 +41,25 @@ impl CriticalLink {
|
|||
}
|
||||
|
||||
/// A summary of the connectivity of a mesh.
|
||||
///
|
||||
/// 网格连通性的摘要。
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct MeshSummary {
|
||||
/// The number of terminals.
|
||||
///
|
||||
/// 终端的数量。
|
||||
pub node_count: usize,
|
||||
/// The number of directed links.
|
||||
///
|
||||
/// 有向链路的数量。
|
||||
pub edge_count: usize,
|
||||
/// The number of components when the links are treated as undirected.
|
||||
///
|
||||
/// 把链路视为无向时的分量数。
|
||||
pub components: usize,
|
||||
/// The number of strongly connected components.
|
||||
///
|
||||
/// 强连通分量的数量。
|
||||
pub strongly_connected_components: usize,
|
||||
/// The smallest number of independent paths between any two distinct
|
||||
/// terminals, or `None` when there are fewer than two terminals.
|
||||
|
|
@ -45,6 +67,12 @@ pub struct MeshSummary {
|
|||
/// This is the worst connection in the mesh. A value of one means some
|
||||
/// pair of terminals relies on a single link and the mesh has no
|
||||
/// redundancy anywhere.
|
||||
///
|
||||
/// 任意两个不同终端之间独立路径条数的最小值;终端少于两个时返回
|
||||
/// `None`。
|
||||
///
|
||||
/// 这是网格中最差的连接。值为一意味着某对终端依赖单条链路,网格
|
||||
/// 处处都无冗余。
|
||||
pub minimum_connectivity: Option<usize>,
|
||||
}
|
||||
|
||||
|
|
@ -53,6 +81,11 @@ pub struct MeshSummary {
|
|||
/// The mesh wraps a topology and adds the connectivity measures a mesh
|
||||
/// application needs. It does not own a schedule or a traffic model; those
|
||||
/// belong to the caller.
|
||||
///
|
||||
/// 由链路连接的终端构成的网格。
|
||||
///
|
||||
/// 网格封装一个拓扑并加入网格应用所需的连通性度量。它不拥有调度或业务
|
||||
/// 模型;那些属于调用方。
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Mesh {
|
||||
topology: Topology,
|
||||
|
|
@ -60,32 +93,44 @@ pub struct Mesh {
|
|||
|
||||
impl Mesh {
|
||||
/// Creates a mesh over a topology.
|
||||
///
|
||||
/// 在某拓扑之上创建网格。
|
||||
pub const fn new(topology: Topology) -> Self {
|
||||
Self { topology }
|
||||
}
|
||||
|
||||
/// Returns the underlying topology.
|
||||
///
|
||||
/// 返回底层拓扑。
|
||||
pub const fn topology(&self) -> &Topology {
|
||||
&self.topology
|
||||
}
|
||||
|
||||
/// Returns the number of terminals.
|
||||
///
|
||||
/// 返回终端的数量。
|
||||
pub fn node_count(&self) -> usize {
|
||||
self.topology.node_count()
|
||||
}
|
||||
|
||||
/// Returns the number of links.
|
||||
///
|
||||
/// 返回链路的数量。
|
||||
pub fn edge_count(&self) -> usize {
|
||||
self.topology.edge_count()
|
||||
}
|
||||
|
||||
/// Returns `true` when every terminal reaches every other, treating the
|
||||
/// links as undirected.
|
||||
///
|
||||
/// 把链路视为无向时,当每个终端都能到达其余每个终端,返回 `true`。
|
||||
pub fn is_connected(&self) -> bool {
|
||||
self.topology.is_connected()
|
||||
}
|
||||
|
||||
/// Returns the terminals reachable from a terminal.
|
||||
///
|
||||
/// 返回自某终端可达的各终端。
|
||||
pub fn reachable_from(&self, source: usize) -> Vec<usize> {
|
||||
reachable_from(&self.topology, source)
|
||||
}
|
||||
|
|
@ -94,6 +139,10 @@ impl Mesh {
|
|||
///
|
||||
/// Returns `None` when either terminal is out of range or the two are
|
||||
/// the same.
|
||||
///
|
||||
/// 返回两个终端之间独立路径的条数。
|
||||
///
|
||||
/// 任一终端越界或两者相同时返回 `None`。
|
||||
pub fn edge_connectivity(&self, source: usize, destination: usize) -> Option<usize> {
|
||||
edge_connectivity(&self.topology, source, destination)
|
||||
}
|
||||
|
|
@ -102,6 +151,10 @@ impl Mesh {
|
|||
/// distinct terminals.
|
||||
///
|
||||
/// Returns `None` when there are fewer than two terminals.
|
||||
///
|
||||
/// 返回任意两个不同终端之间独立路径条数的最小值。
|
||||
///
|
||||
/// 终端少于两个时返回 `None`。
|
||||
pub fn minimum_connectivity(&self) -> Option<usize> {
|
||||
let node_count = self.topology.node_count();
|
||||
if node_count < 2 {
|
||||
|
|
@ -134,6 +187,18 @@ impl Mesh {
|
|||
/// Links that are not bridges are omitted, so an empty result means
|
||||
/// every link lies on a cycle and the mesh survives any single link
|
||||
/// failure without splitting.
|
||||
///
|
||||
/// 返回移除后会增加连通分量数的那些链路,把每条链路视为无向。
|
||||
///
|
||||
/// 它们是网格底层无向图的桥。一条链路只报告一次,即便它有双向,
|
||||
/// 因为一次失效是整条链路失效而非其中一个方向。
|
||||
///
|
||||
/// 每个候选通过在两方向移除该链路并比较分量数来发现,这精确但每条
|
||||
/// 链路要花一次遍历。对卫星网所呈现的图规模而言这是可接受的,且比
|
||||
/// 线性时间的桥查找算法更易验证。
|
||||
///
|
||||
/// 非桥的链路被省略,故空结果意味着每条链路都在某个环上,网格在
|
||||
/// 任何单条链路失效下都不会裂开。
|
||||
pub fn critical_links(&self) -> Vec<CriticalLink> {
|
||||
let baseline = self.topology.connected_components();
|
||||
let mut critical = Vec::new();
|
||||
|
|
@ -142,6 +207,7 @@ impl Mesh {
|
|||
for edge in self.topology.edges() {
|
||||
// Canonicalize the pair so that the two directions of one link
|
||||
// are considered together and reported once.
|
||||
// 规范化该点对,使一条链路的两个方向被一并考虑并只报告一次。
|
||||
let pair = if edge.from <= edge.to {
|
||||
(edge.from, edge.to)
|
||||
} else {
|
||||
|
|
@ -154,6 +220,7 @@ impl Mesh {
|
|||
|
||||
// Remove the link in every direction in which it is present,
|
||||
// which is what a link failure does.
|
||||
// 在它出现的每个方向上移除该链路,这正是链路失效所做的。
|
||||
let mut without = self.topology.clone();
|
||||
let _ = without.remove_edge(pair.0, pair.1);
|
||||
let _ = without.remove_edge(pair.1, pair.0);
|
||||
|
|
@ -172,6 +239,11 @@ impl Mesh {
|
|||
/// This is the condition for the mesh to have a single link failure
|
||||
/// tolerance, which is the minimum redundancy a network carrying traffic
|
||||
/// without interruption should have.
|
||||
///
|
||||
/// 当网格在任何单条链路失效下都不裂开时返回 `true`。
|
||||
///
|
||||
/// 这是网格具备单链路失效容错的条件,而这是不中断地承载业务的网络
|
||||
/// 应有的最低冗余。
|
||||
pub fn survives_single_link_failure(&self) -> bool {
|
||||
self.critical_links().is_empty()
|
||||
}
|
||||
|
|
@ -181,11 +253,18 @@ impl Mesh {
|
|||
/// For a mesh of directed links this counts the pieces that can route
|
||||
/// internally. A value above one means some terminals cannot be reached
|
||||
/// from some others.
|
||||
///
|
||||
/// 返回强连通分量的数量。
|
||||
///
|
||||
/// 对有向链路的网格而言,它统计可各自内部路由的块数。大于一的值
|
||||
/// 意味着有些终端无法从另一些到达。
|
||||
pub fn strongly_connected_components(&self) -> usize {
|
||||
strongly_connected_components(&self.topology)
|
||||
}
|
||||
|
||||
/// Returns a summary of the mesh connectivity.
|
||||
///
|
||||
/// 返回网格连通性的摘要。
|
||||
pub fn summarise(&self) -> MeshSummary {
|
||||
MeshSummary {
|
||||
node_count: self.topology.node_count(),
|
||||
|
|
|
|||
|
|
@ -4,18 +4,31 @@
|
|||
///
|
||||
/// A step records the link traversed and the cost of that link, so a caller
|
||||
/// can attribute a route's total cost to its parts.
|
||||
///
|
||||
/// 路由的一跳。
|
||||
///
|
||||
/// 一个步骤记录所穿越的链路及其代价,使调用方能把路由的总代价归因于
|
||||
/// 各部分。
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct RouteStep {
|
||||
/// The node the step leaves.
|
||||
///
|
||||
/// 该步骤离开的节点。
|
||||
pub from: usize,
|
||||
/// The node the step arrives at.
|
||||
///
|
||||
/// 该步骤到达的节点。
|
||||
pub to: usize,
|
||||
/// The cost of the link.
|
||||
///
|
||||
/// 该链路的代价。
|
||||
pub cost: f64,
|
||||
}
|
||||
|
||||
impl RouteStep {
|
||||
/// Creates a step.
|
||||
///
|
||||
/// 创建一个步骤。
|
||||
pub const fn new(from: usize, to: usize, cost: f64) -> Self {
|
||||
Self { from, to, cost }
|
||||
}
|
||||
|
|
@ -26,13 +39,24 @@ impl RouteStep {
|
|||
/// The node list includes both endpoints, so a route of one hop has two
|
||||
/// nodes and one step, and a route from a node to itself has one node and no
|
||||
/// steps.
|
||||
///
|
||||
/// 两个节点之间的路由。
|
||||
///
|
||||
/// 节点列表包含两个端点,故一跳的路由有两个节点和一个步骤,自某节点到
|
||||
/// 其自身的路由有一个节点且没有步骤。
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Route {
|
||||
/// The nodes in order, from the source to the destination.
|
||||
///
|
||||
/// 按次序排列的节点,从源到目的地。
|
||||
pub nodes: Vec<usize>,
|
||||
/// The links traversed, in order.
|
||||
///
|
||||
/// 按次序穿越的链路。
|
||||
pub steps: Vec<RouteStep>,
|
||||
/// The total cost of the route.
|
||||
///
|
||||
/// 该路由的总代价。
|
||||
pub cost: f64,
|
||||
}
|
||||
|
||||
|
|
@ -41,12 +65,18 @@ impl Route {
|
|||
///
|
||||
/// The cost is taken as the sum of the step costs, so a caller cannot
|
||||
/// make the total disagree with the parts.
|
||||
///
|
||||
/// 由其节点与步骤创建路由。
|
||||
///
|
||||
/// 代价取各步骤代价之和,故调用方无法使总计与各部分不一致。
|
||||
pub fn new(nodes: Vec<usize>, steps: Vec<RouteStep>) -> Self {
|
||||
let cost = steps.iter().map(|step| step.cost).sum();
|
||||
Self { nodes, steps, cost }
|
||||
}
|
||||
|
||||
/// Returns the number of hops.
|
||||
///
|
||||
/// 返回跳数。
|
||||
pub fn hop_count(&self) -> usize {
|
||||
self.steps.len()
|
||||
}
|
||||
|
|
@ -54,6 +84,10 @@ impl Route {
|
|||
/// Returns the source node.
|
||||
///
|
||||
/// Returns `None` when the route has no nodes.
|
||||
///
|
||||
/// 返回源节点。
|
||||
///
|
||||
/// 路由没有节点时返回 `None`。
|
||||
pub fn source(&self) -> Option<usize> {
|
||||
self.nodes.first().copied()
|
||||
}
|
||||
|
|
@ -61,6 +95,10 @@ impl Route {
|
|||
/// Returns the destination node.
|
||||
///
|
||||
/// Returns `None` when the route has no nodes.
|
||||
///
|
||||
/// 返回目的地节点。
|
||||
///
|
||||
/// 路由没有节点时返回 `None`。
|
||||
pub fn destination(&self) -> Option<usize> {
|
||||
self.nodes.last().copied()
|
||||
}
|
||||
|
|
@ -70,6 +108,11 @@ impl Route {
|
|||
/// The costs are unchanged, because a route reversed traverses the same
|
||||
/// links. This is only correct when every link is present in both
|
||||
/// directions with the same cost, which a caller must ensure.
|
||||
///
|
||||
/// 返回按相反方向穿越的路由。
|
||||
///
|
||||
/// 各代价不变,因为反转后的路由穿越同样的链路。仅当每条链路都以
|
||||
/// 相同代价双向存在时才正确,这一点须由调用方保证。
|
||||
pub fn reversed(&self) -> Self {
|
||||
let nodes = self.nodes.iter().rev().copied().collect();
|
||||
let steps = self
|
||||
|
|
@ -82,32 +125,49 @@ impl Route {
|
|||
}
|
||||
|
||||
/// Returns `true` when the route passes through a node.
|
||||
///
|
||||
/// 当该路由经过某节点时返回 `true`。
|
||||
pub fn passes_through(&self, node: usize) -> bool {
|
||||
self.nodes.contains(&node)
|
||||
}
|
||||
|
||||
/// Returns the position of a node in the route, if it is on it.
|
||||
///
|
||||
/// 返回某节点在路由中的位置(若在该路由上)。
|
||||
pub fn position_of(&self, node: usize) -> Option<usize> {
|
||||
self.nodes.iter().position(|candidate| *candidate == node)
|
||||
}
|
||||
}
|
||||
|
||||
/// A route with the interval over which it is valid.
|
||||
///
|
||||
/// 一条路由及其有效的时段。
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct RouteLeg {
|
||||
/// The route.
|
||||
///
|
||||
/// 该路由。
|
||||
pub route: Route,
|
||||
/// The time from which the route is valid, in seconds.
|
||||
///
|
||||
/// 该路由开始有效的时间,单位为秒。
|
||||
pub start_seconds: f64,
|
||||
/// The time until which the route is valid, in seconds.
|
||||
///
|
||||
/// This is the time of the topology change that invalidates the route.
|
||||
/// It is infinite when the route is valid for all later times.
|
||||
///
|
||||
/// 该路由保持有效直到的时间,单位为秒。
|
||||
///
|
||||
/// 这是使该路由失效的拓扑变化的时间。当该路由对其后所有时间都有效
|
||||
/// 时它为无穷。
|
||||
pub end_seconds: f64,
|
||||
}
|
||||
|
||||
impl RouteLeg {
|
||||
/// Creates a route leg.
|
||||
///
|
||||
/// 创建一段路由。
|
||||
pub const fn new(route: Route, start_seconds: f64, end_seconds: f64) -> Self {
|
||||
Self {
|
||||
route,
|
||||
|
|
@ -119,6 +179,10 @@ impl RouteLeg {
|
|||
/// Returns the duration for which the route holds, in seconds.
|
||||
///
|
||||
/// Returns infinity when the route is valid for all later times.
|
||||
///
|
||||
/// 返回该路由保持的时长,单位为秒。
|
||||
///
|
||||
/// 该路由对其后所有时间都有效时返回无穷。
|
||||
pub fn duration_seconds(&self) -> f64 {
|
||||
self.end_seconds - self.start_seconds
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue