aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm
diff options
context:
space:
mode:
Diffstat (limited to 'src/swarm')
-rw-r--r--src/swarm/tree.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/swarm/tree.rs b/src/swarm/tree.rs
index 0aef94c..81004e8 100644
--- a/src/swarm/tree.rs
+++ b/src/swarm/tree.rs
@@ -370,6 +370,41 @@ pub(crate) async fn own_parent(state: &AppState, writer: &str) -> Option<String>
parent(&graph, &distance, &reached, &round_trip, state.local_id()).map(str::to_owned)
}
+/// Where we are in `writer`'s tree, as we see it: our distance from the writer, our
+/// parent (`parent`), and the neighbours we reach that come before us (whom we could
+/// take). None while the member list isn't known, or the writer or we aren't in it.
+#[cfg(test)]
+pub(crate) struct Place {
+ pub(crate) distance: u32,
+ pub(crate) parent: Option<String>,
+ pub(crate) before: Vec<String>,
+}
+
+#[cfg(test)]
+pub(crate) async fn own_place(state: &AppState, writer: &str) -> Option<Place> {
+ let (graph, distance) = distances(state, topology::pair_key(writer))?;
+ let known = known_reaches(state, &graph).await;
+ let reached = |by: &str, member: &str| known.reached(by, member);
+ let round_trip = |by: &str, member: &str| known.round_trip(by, member);
+ let me = state.local_id();
+ let its_rank = rank(&graph, &distance, &reached, me)?;
+ let before = graph
+ .get(me)
+ .into_iter()
+ .flatten()
+ .filter(|candidate| {
+ rank(&graph, &distance, &reached, candidate).is_some_and(|r| r < its_rank)
+ && reached(me, candidate)
+ })
+ .cloned()
+ .collect();
+ Some(Place {
+ distance: distance[me],
+ parent: parent(&graph, &distance, &reached, &round_trip, me).map(str::to_owned),
+ before,
+ })
+}
+
/// `Latencies` of our own tree, by `latency(from, to)` in milliseconds; None while the
/// member list isn't known, or we aren't in it, or the tree reaches nobody.
#[cfg(test)]