state-res: Replace unwraps with expect or errors
This commit is contained in:
parent
01515aea41
commit
318f3186ad
@ -46,7 +46,7 @@ fn lexico_topo_sort(c: &mut Criterion) {
|
|||||||
};
|
};
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let _ = StateResolution::lexicographical_topological_sort(&graph, |id| {
|
let _ = StateResolution::lexicographical_topological_sort(&graph, |id| {
|
||||||
(0, MilliSecondsSinceUnixEpoch(uint!(0)), id.clone())
|
Ok((0, MilliSecondsSinceUnixEpoch(uint!(0)), id.clone()))
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -136,7 +136,7 @@ impl StateResolution {
|
|||||||
&control_events,
|
&control_events,
|
||||||
&all_conflicted,
|
&all_conflicted,
|
||||||
&fetch_event,
|
&fetch_event,
|
||||||
);
|
)?;
|
||||||
|
|
||||||
debug!("sorted control events: {}", sorted_control_levels.len());
|
debug!("sorted control events: {}", sorted_control_levels.len());
|
||||||
trace!("{:?}", sorted_control_levels);
|
trace!("{:?}", sorted_control_levels);
|
||||||
@ -174,7 +174,7 @@ impl StateResolution {
|
|||||||
debug!("power event: {:?}", power_event);
|
debug!("power event: {:?}", power_event);
|
||||||
|
|
||||||
let sorted_left_events =
|
let sorted_left_events =
|
||||||
StateResolution::mainline_sort(&events_to_resolve, power_event, &fetch_event);
|
StateResolution::mainline_sort(&events_to_resolve, power_event, &fetch_event)?;
|
||||||
|
|
||||||
trace!("events left, sorted: {:?}", sorted_left_events.iter().collect::<Vec<_>>());
|
trace!("events left, sorted: {:?}", sorted_left_events.iter().collect::<Vec<_>>());
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ impl StateResolution {
|
|||||||
events_to_sort: &[EventId],
|
events_to_sort: &[EventId],
|
||||||
auth_diff: &HashSet<EventId>,
|
auth_diff: &HashSet<EventId>,
|
||||||
fetch_event: F,
|
fetch_event: F,
|
||||||
) -> Vec<EventId>
|
) -> Result<Vec<EventId>>
|
||||||
where
|
where
|
||||||
E: Event,
|
E: Event,
|
||||||
F: Fn(&EventId) -> Option<Arc<E>>,
|
F: Fn(&EventId) -> Option<Arc<E>>,
|
||||||
@ -284,15 +284,15 @@ impl StateResolution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StateResolution::lexicographical_topological_sort(&graph, |event_id| {
|
StateResolution::lexicographical_topological_sort(&graph, |event_id| {
|
||||||
let ev = fetch_event(event_id).unwrap();
|
let ev = fetch_event(event_id).ok_or_else(|| Error::NotFound("".into()))?;
|
||||||
let pl = event_to_pl.get(event_id).unwrap();
|
let pl = event_to_pl.get(event_id).ok_or_else(|| Error::NotFound("".into()))?;
|
||||||
|
|
||||||
debug!("{:?}", (-*pl, ev.origin_server_ts(), &ev.event_id()));
|
debug!("{:?}", (-*pl, ev.origin_server_ts(), &ev.event_id()));
|
||||||
|
|
||||||
// This return value is the key used for sorting events,
|
// This return value is the key used for sorting events,
|
||||||
// events are then sorted by power level, time,
|
// events are then sorted by power level, time,
|
||||||
// and lexically by event_id.
|
// and lexically by event_id.
|
||||||
(-*pl, ev.origin_server_ts(), ev.event_id().clone())
|
Ok((-*pl, ev.origin_server_ts(), ev.event_id().clone()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,9 +302,9 @@ impl StateResolution {
|
|||||||
pub fn lexicographical_topological_sort<F>(
|
pub fn lexicographical_topological_sort<F>(
|
||||||
graph: &HashMap<EventId, HashSet<EventId>>,
|
graph: &HashMap<EventId, HashSet<EventId>>,
|
||||||
key_fn: F,
|
key_fn: F,
|
||||||
) -> Vec<EventId>
|
) -> Result<Vec<EventId>>
|
||||||
where
|
where
|
||||||
F: Fn(&EventId) -> (i64, MilliSecondsSinceUnixEpoch, EventId),
|
F: Fn(&EventId) -> Result<(i64, MilliSecondsSinceUnixEpoch, EventId)>,
|
||||||
{
|
{
|
||||||
info!("starting lexicographical topological sort");
|
info!("starting lexicographical topological sort");
|
||||||
// NOTE: an event that has no incoming edges happened most recently,
|
// NOTE: an event that has no incoming edges happened most recently,
|
||||||
@ -314,12 +314,12 @@ impl StateResolution {
|
|||||||
// outgoing edges, c.f.
|
// outgoing edges, c.f.
|
||||||
// https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm
|
// https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm
|
||||||
|
|
||||||
// TODO make the HashSet conversion cleaner ??
|
|
||||||
// outdegree_map is an event referring to the events before it, the
|
// outdegree_map is an event referring to the events before it, the
|
||||||
// more outdegree's the more recent the event.
|
// more outdegree's the more recent the event.
|
||||||
let mut outdegree_map = graph.clone();
|
let mut outdegree_map = graph.clone();
|
||||||
|
|
||||||
// The number of events that depend on the given event (the eventId key)
|
// The number of events that depend on the given event (the EventId key)
|
||||||
|
// How many events reference this event in the DAG as a parent
|
||||||
let mut reverse_graph = HashMap::new();
|
let mut reverse_graph = HashMap::new();
|
||||||
|
|
||||||
// Vec of nodes that have zero out degree, least recent events.
|
// Vec of nodes that have zero out degree, least recent events.
|
||||||
@ -329,7 +329,7 @@ impl StateResolution {
|
|||||||
if edges.is_empty() {
|
if edges.is_empty() {
|
||||||
// The `Reverse` is because rusts `BinaryHeap` sorts largest -> smallest we need
|
// The `Reverse` is because rusts `BinaryHeap` sorts largest -> smallest we need
|
||||||
// smallest -> largest
|
// smallest -> largest
|
||||||
zero_outdegree.push(Reverse((key_fn(node), node)));
|
zero_outdegree.push(Reverse((key_fn(node)?, node)));
|
||||||
}
|
}
|
||||||
|
|
||||||
reverse_graph.entry(node).or_insert(hashset![]);
|
reverse_graph.entry(node).or_insert(hashset![]);
|
||||||
@ -345,14 +345,17 @@ impl StateResolution {
|
|||||||
// Destructure the `Reverse` and take the smallest `node` each time
|
// Destructure the `Reverse` and take the smallest `node` each time
|
||||||
while let Some(Reverse((_, node))) = heap.pop() {
|
while let Some(Reverse((_, node))) = heap.pop() {
|
||||||
let node: &EventId = node;
|
let node: &EventId = node;
|
||||||
for parent in reverse_graph.get(node).unwrap() {
|
for parent in reverse_graph.get(node).expect("EventId in heap is also in reverse_graph")
|
||||||
|
{
|
||||||
// The number of outgoing edges this node has
|
// The number of outgoing edges this node has
|
||||||
let out = outdegree_map.get_mut(parent).unwrap();
|
let out = outdegree_map
|
||||||
|
.get_mut(parent)
|
||||||
|
.expect("outdegree_map knows of all referenced EventIds");
|
||||||
|
|
||||||
// Only push on the heap once older events have been cleared
|
// Only push on the heap once older events have been cleared
|
||||||
out.remove(node);
|
out.remove(node);
|
||||||
if out.is_empty() {
|
if out.is_empty() {
|
||||||
heap.push(Reverse((key_fn(parent), parent)));
|
heap.push(Reverse((key_fn(parent)?, parent)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +363,7 @@ impl StateResolution {
|
|||||||
sorted.push(node.clone());
|
sorted.push(node.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
sorted
|
Ok(sorted)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the power level for the sender of `event_id` or return a default value of zero.
|
/// Find the power level for the sender of `event_id` or return a default value of zero.
|
||||||
@ -516,7 +519,7 @@ impl StateResolution {
|
|||||||
to_sort: &[EventId],
|
to_sort: &[EventId],
|
||||||
resolved_power_level: Option<&EventId>,
|
resolved_power_level: Option<&EventId>,
|
||||||
fetch_event: F,
|
fetch_event: F,
|
||||||
) -> Vec<EventId>
|
) -> Result<Vec<EventId>>
|
||||||
where
|
where
|
||||||
E: Event,
|
E: Event,
|
||||||
F: Fn(&EventId) -> Option<Arc<E>>,
|
F: Fn(&EventId) -> Option<Arc<E>>,
|
||||||
@ -525,7 +528,7 @@ impl StateResolution {
|
|||||||
|
|
||||||
// There are no EventId's to sort, bail.
|
// There are no EventId's to sort, bail.
|
||||||
if to_sort.is_empty() {
|
if to_sort.is_empty() {
|
||||||
return vec![];
|
return Ok(vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut mainline = vec![];
|
let mut mainline = vec![];
|
||||||
@ -533,11 +536,13 @@ impl StateResolution {
|
|||||||
while let Some(p) = pl {
|
while let Some(p) = pl {
|
||||||
mainline.push(p.clone());
|
mainline.push(p.clone());
|
||||||
|
|
||||||
let event = fetch_event(&p).unwrap();
|
let event =
|
||||||
|
fetch_event(&p).ok_or_else(|| Error::NotFound(format!("Failed to find {}", p)))?;
|
||||||
let auth_events = &event.auth_events();
|
let auth_events = &event.auth_events();
|
||||||
pl = None;
|
pl = None;
|
||||||
for aid in auth_events {
|
for aid in auth_events {
|
||||||
let ev = fetch_event(aid).unwrap();
|
let ev = fetch_event(aid)
|
||||||
|
.ok_or_else(|| Error::NotFound(format!("Failed to find {}", aid)))?;
|
||||||
if is_type_and_key(&ev, EventType::RoomPowerLevels, "") {
|
if is_type_and_key(&ev, EventType::RoomPowerLevels, "") {
|
||||||
pl = Some(aid.clone());
|
pl = Some(aid.clone());
|
||||||
break;
|
break;
|
||||||
@ -582,7 +587,7 @@ impl StateResolution {
|
|||||||
let mut sort_event_ids = order_map.keys().map(|&k| k.clone()).collect::<Vec<_>>();
|
let mut sort_event_ids = order_map.keys().map(|&k| k.clone()).collect::<Vec<_>>();
|
||||||
sort_event_ids.sort_by_key(|sort_id| order_map.get(sort_id).unwrap());
|
sort_event_ids.sort_by_key(|sort_id| order_map.get(sort_id).unwrap());
|
||||||
|
|
||||||
sort_event_ids
|
Ok(sort_event_ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the mainline depth from the `mainline_map` or finds a power_level event
|
/// Get the mainline depth from the `mainline_map` or finds a power_level event
|
||||||
|
@ -32,10 +32,9 @@ fn test_event_sort() {
|
|||||||
let sorted_power_events =
|
let sorted_power_events =
|
||||||
StateResolution::reverse_topological_power_sort(&power_events, &auth_chain, |id| {
|
StateResolution::reverse_topological_power_sort(&power_events, &auth_chain, |id| {
|
||||||
events.get(id).map(Arc::clone)
|
events.get(id).map(Arc::clone)
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// This is a TODO in conduit
|
|
||||||
// TODO we may be able to skip this since they are resolved according to spec
|
|
||||||
let resolved_power = StateResolution::iterative_auth_check(
|
let resolved_power = StateResolution::iterative_auth_check(
|
||||||
&RoomVersion::version_6(),
|
&RoomVersion::version_6(),
|
||||||
&sorted_power_events,
|
&sorted_power_events,
|
||||||
@ -53,7 +52,8 @@ fn test_event_sort() {
|
|||||||
|
|
||||||
let sorted_event_ids = StateResolution::mainline_sort(&events_to_sort, power_level, |id| {
|
let sorted_event_ids = StateResolution::mainline_sort(&events_to_sort, power_level, |id| {
|
||||||
events.get(id).map(Arc::clone)
|
events.get(id).map(Arc::clone)
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec![
|
vec![
|
||||||
|
@ -286,8 +286,9 @@ fn test_lexicographical_sort() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let res = StateResolution::lexicographical_topological_sort(&graph, |id| {
|
let res = StateResolution::lexicographical_topological_sort(&graph, |id| {
|
||||||
(0, MilliSecondsSinceUnixEpoch(uint!(0)), id.clone())
|
Ok((0, MilliSecondsSinceUnixEpoch(uint!(0)), id.clone()))
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec!["o", "l", "n", "m", "p"],
|
vec!["o", "l", "n", "m", "p"],
|
||||||
|
@ -80,8 +80,10 @@ pub fn do_check(
|
|||||||
// Resolve the current state and add it to the state_at_event map then continue
|
// Resolve the current state and add it to the state_at_event map then continue
|
||||||
// on in "time"
|
// on in "time"
|
||||||
for node in StateResolution::lexicographical_topological_sort(&graph, |id| {
|
for node in StateResolution::lexicographical_topological_sort(&graph, |id| {
|
||||||
(0, MilliSecondsSinceUnixEpoch(uint!(0)), id.clone())
|
Ok((0, MilliSecondsSinceUnixEpoch(uint!(0)), id.clone()))
|
||||||
}) {
|
})
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
let fake_event = fake_event_map.get(&node).unwrap();
|
let fake_event = fake_event_map.get(&node).unwrap();
|
||||||
let event_id = fake_event.event_id().clone();
|
let event_id = fake_event.event_id().clone();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user