diff options
Diffstat (limited to 'src/swarm/topology')
| -rw-r--r-- | src/swarm/topology/mod.rs | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/src/swarm/topology/mod.rs b/src/swarm/topology/mod.rs index 30fa56e..df75f46 100644 --- a/src/swarm/topology/mod.rs +++ b/src/swarm/topology/mod.rs @@ -133,31 +133,54 @@ pub(crate) fn is_neighbour(state: &AppState, peer: &str) -> bool { pub(crate) fn intended_graph(state: &AppState) -> Option<BTreeMap<String, BTreeSet<String>>> { let view = state.neighbours.read_or_recover(); let view = view.as_ref()?; - let unreachable = |member: &str| view.unreachable.contains(member); - let stable = |member: &str| view.stable.contains(member); let graph = view .members .iter() - .map(|member| { - let neighbours = if member == state.local_id() { - view.neighbours.clone() - } else { - let own = view.transports.get(member).cloned().unwrap_or_default(); - neighbours_across( - &view.transports, - member, - &own, - view.k, - &unreachable, - &stable, - ) - }; - (member.clone(), neighbours) - }) + .map(|member| (member.clone(), view.neighbours_of(state.local_id(), member))) .collect(); Some(graph) } +/// `member`'s neighbours as the member list makes them, as this node sees it (as in +/// `intended_graph`); None until the view is known, or for one the list doesn't have. +pub(crate) fn neighbours_of(state: &AppState, member: &str) -> Option<BTreeSet<String>> { + let view = state.neighbours.read_or_recover(); + let view = view.as_ref()?; + view.members + .iter() + .any(|listed| listed == member) + .then(|| view.neighbours_of(state.local_id(), member)) +} + +/// The transports `member` is on, by the member list (the schemes of its addresses); +/// ours as we are on them. None known: empty. +pub(crate) fn transports_of(state: &AppState, member: &str) -> BTreeSet<String> { + let view = state.neighbours.read_or_recover(); + match view.as_ref() { + Some(view) if member == state.local_id() => view.local_transports.clone(), + Some(view) => view.transports.get(member).cloned().unwrap_or_default(), + None if member == state.local_id() => state.transport.transports().into_iter().collect(), + None => BTreeSet::new(), + } +} + +impl NeighbourView { + fn neighbours_of(&self, local: &str, member: &str) -> BTreeSet<String> { + if member == local { + return self.neighbours.clone(); + } + let own = self.transports.get(member).cloned().unwrap_or_default(); + neighbours_across( + &self.transports, + member, + &own, + self.k, + &|member| self.unreachable.contains(member), + &|member| self.stable.contains(member), + ) + } +} + /// How the neighbours changed. pub(crate) struct NeighbourChange { pub(crate) added: Vec<String>, |
