GuardMgr: Refactor UniverseRef to contains Arcs.

We already _have_ these Arc<>s whenever we construct a UniverseRef,
so there's no real point in using &refs and making these so
hard to construct.
This commit is contained in:
Nick Mathewson 2022-11-04 13:46:12 -04:00
parent 7fa08140cf
commit 25d7924832
3 changed files with 31 additions and 27 deletions

View File

@ -137,20 +137,20 @@ pub type BridgeDescList = HashMap<Arc<BridgeConfig>, Result<BridgeDesc, Box<dyn
//
// TODO pt-client: I doubt that this type is in its final form.
#[derive(Debug, Clone)]
pub(crate) struct BridgeSet<'a> {
pub(crate) struct BridgeSet {
/// When did this BridgeSet last change its listed bridges?
config_last_changed: SystemTime,
/// The configured bridges.
config: &'a [BridgeConfig],
config: Arc<[BridgeConfig]>,
/// A map from those bridges to their descriptors. It may contain elements
/// that are not in `config`.
descs: Option<&'a BridgeDescList>,
descs: Option<Arc<BridgeDescList>>,
}
impl<'a> BridgeSet<'a> {
impl BridgeSet {
/// Create a new `BridgeSet` from its configuration.
#[allow(dead_code)] // TODO pt-client remove
pub(crate) fn new(config: &'a [BridgeConfig], descs: Option<&'a BridgeDescList>) -> Self {
pub(crate) fn new(config: Arc<[BridgeConfig]>, descs: Option<Arc<BridgeDescList>>) -> Self {
Self {
config_last_changed: SystemTime::now(), // TODO pt-client wrong.
config,
@ -177,8 +177,8 @@ impl<'a> BridgeSet<'a> {
/// Return a BridgeRelay wrapping the provided configuration, plus any known
/// descriptor for that configuration.
fn relay_by_bridge(&self, bridge: &'a BridgeConfig) -> BridgeRelay<'a> {
let desc = match self.descs.and_then(|d| d.get(bridge)) {
fn relay_by_bridge<'a>(&'a self, bridge: &'a BridgeConfig) -> BridgeRelay<'a> {
let desc = match self.descs.as_ref().and_then(|d| d.get(bridge)) {
Some(Ok(b)) => Some(b.clone()),
_ => None,
};
@ -214,7 +214,7 @@ impl<'a> BridgeSet<'a> {
}
}
impl<'a> Universe for BridgeSet<'a> {
impl Universe for BridgeSet {
fn contains<T: tor_linkspec::ChanTarget>(&self, guard: &T) -> Option<bool> {
match self.bridge_relay_by_guard(guard) {
CandidateStatus::Present(_) => Some(true),

View File

@ -772,34 +772,38 @@ impl GuardMgrInner {
}
}
/// Return the latest `BridgeSet` based on our `BridgeDescProvider` and our
/// configured bridges.
#[cfg(feature = "bridge-client")]
fn latest_bridge_set(&self) -> bridge::BridgeSet {
let bridge_descs = self.latest_bridge_desc_list();
let bridge_config = self.configured_bridges.clone();
bridge::BridgeSet::new(bridge_config, bridge_descs)
}
/// Run a function that takes `&mut self` and an optional [`UniverseRef`].
///
/// We try to get a universe from the appropriate source for the current
/// active guard set.
fn with_opt_universe<F, T>(&mut self, func: F) -> T
where
F: for<'a> FnOnce(&mut Self, Option<UniverseRef<'a>>) -> T,
F: FnOnce(&mut Self, Option<&UniverseRef>) -> T,
{
// TODO pt-client: soon, make the function take an GuardSet and a set
// of parameters, so we can't get the active set wrong.
match self.guards.active_set.universe_type() {
UniverseType::NetDir => {
if let Some(nd) = self.timely_netdir() {
func(self, Some(UniverseRef::NetDir(nd.as_ref())))
func(self, Some(&UniverseRef::NetDir(nd)))
} else {
func(self, None)
}
}
#[cfg(feature = "bridge-client")]
UniverseType::BridgeSet => {
let bridge_descs = self.latest_bridge_desc_list();
let bridge_config = self.configured_bridges.clone();
let bridge_set = bridge::BridgeSet::new(
bridge_config.as_ref(),
bridge_descs.as_ref().map(|b| b.as_ref()),
);
func(self, Some(UniverseRef::BridgeSet(bridge_set)))
}
UniverseType::BridgeSet => func(
self,
Some(&UniverseRef::BridgeSet(self.latest_bridge_set())),
),
}
}
@ -818,7 +822,7 @@ impl GuardMgrInner {
&this.params,
now,
this.guards.active_guards_mut(),
univ.as_ref(),
univ,
);
});
}
@ -1290,12 +1294,12 @@ impl GuardMgrInner {
&this.params,
wallclock,
this.guards.active_guards_mut(),
Some(&univ),
Some(univ),
);
if this.guards.active_guards_mut().extend_sample_as_needed(
wallclock,
&this.params,
&univ,
univ,
) {
this.guards
.active_guards_mut()

View File

@ -1,7 +1,7 @@
//! This module defines and implements traits used to create a guard sample from
//! either bridges or relays.
use std::time::SystemTime;
use std::{sync::Arc, time::SystemTime};
use tor_linkspec::{ByRelayIds, ChanTarget, HasRelayIds, OwnedChanTarget};
use tor_netdir::{NetDir, Relay, RelayWeight};
@ -189,15 +189,15 @@ impl Universe for NetDir {
///
/// This enum exists because `Universe` is not dyn-compatible.
#[derive(Clone, Debug)]
pub(crate) enum UniverseRef<'a> {
pub(crate) enum UniverseRef {
/// A reference to a netdir.
NetDir(&'a NetDir),
NetDir(Arc<NetDir>),
/// A BridgeSet (which is always references internally)
#[cfg(feature = "bridge-client")]
BridgeSet(crate::bridge::BridgeSet<'a>),
BridgeSet(crate::bridge::BridgeSet),
}
impl<'a> Universe for UniverseRef<'a> {
impl Universe for UniverseRef {
fn contains<T: ChanTarget>(&self, guard: &T) -> Option<bool> {
match self {
UniverseRef::NetDir(r) => r.contains(guard),