state-res: Make resolve more general by using impl IntoIterator for state_sets

This commit is contained in:
Jonas Platte 2021-09-13 16:01:43 +02:00
parent 3830dcddc2
commit 889406b6c2
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
3 changed files with 28 additions and 30 deletions

View File

@ -61,10 +61,10 @@ fn resolution_shallow_auth_chain(c: &mut Criterion) {
b.iter(|| { b.iter(|| {
let ev_map = store.0.clone(); let ev_map = store.0.clone();
let state_sets = vec![state_at_bob.clone(), state_at_charlie.clone()]; let state_sets = [&state_at_bob, &state_at_charlie];
let _ = match state_res::resolve( let _ = match state_res::resolve(
&RoomVersionId::Version6, &RoomVersionId::Version6,
&state_sets, state_sets,
state_sets state_sets
.iter() .iter()
.map(|map| { .map(|map| {
@ -125,10 +125,10 @@ fn resolve_deeper_event_set(c: &mut Criterion) {
.collect::<StateMap<_>>(); .collect::<StateMap<_>>();
b.iter(|| { b.iter(|| {
let state_sets = vec![state_set_a.clone(), state_set_b.clone()]; let state_sets = [&state_set_a, &state_set_b];
let _ = match state_res::resolve( let _ = match state_res::resolve(
&RoomVersionId::Version6, &RoomVersionId::Version6,
&state_sets, state_sets,
state_sets state_sets
.iter() .iter()
.map(|map| { .map(|map| {

View File

@ -51,20 +51,21 @@ type EventMap<T> = HashMap<EventId, T>;
/// ///
/// The caller of `resolve` must ensure that all the events are from the same room. Although this /// The caller of `resolve` must ensure that all the events are from the same room. Although this
/// function takes a `RoomId` it does not check that each event is part of the same room. /// function takes a `RoomId` it does not check that each event is part of the same room.
pub fn resolve<E, F>( pub fn resolve<'a, E, F, SSI>(
room_version: &RoomVersionId, room_version: &RoomVersionId,
state_sets: &[StateMap<EventId>], state_sets: impl IntoIterator<IntoIter = SSI>,
auth_chain_sets: Vec<HashSet<EventId>>, auth_chain_sets: Vec<HashSet<EventId>>,
fetch_event: F, fetch_event: F,
) -> Result<StateMap<EventId>> ) -> Result<StateMap<EventId>>
where where
E: Event + Clone, E: Event + Clone,
F: Fn(&EventId) -> Option<E>, F: Fn(&EventId) -> Option<E>,
SSI: Iterator<Item = &'a StateMap<EventId>> + Clone,
{ {
info!("State resolution starting"); info!("State resolution starting");
// Split non-conflicting and conflicting state // Split non-conflicting and conflicting state
let (clean, conflicting) = separate(state_sets); let (clean, conflicting) = separate(state_sets.into_iter());
info!("non conflicting events: {}", clean.len()); info!("non conflicting events: {}", clean.len());
trace!("{:?}", clean); trace!("{:?}", clean);
@ -158,15 +159,15 @@ where
/// State is determined to be conflicting if for the given key (EventType, StateKey) there is not /// State is determined to be conflicting if for the given key (EventType, StateKey) there is not
/// exactly one eventId. This includes missing events, if one state_set includes an event that none /// exactly one eventId. This includes missing events, if one state_set includes an event that none
/// of the other have this is a conflicting event. /// of the other have this is a conflicting event.
fn separate(state_sets: &[StateMap<EventId>]) -> (StateMap<EventId>, StateMap<Vec<EventId>>) { fn separate<'a>(
info!("separating {} sets of events into conflicted/unconflicted", state_sets.len()); state_sets_iter: impl Iterator<Item = &'a StateMap<EventId>> + Clone,
) -> (StateMap<EventId>, StateMap<Vec<EventId>>) {
let mut unconflicted_state = StateMap::new(); let mut unconflicted_state = StateMap::new();
let mut conflicted_state = StateMap::new(); let mut conflicted_state = StateMap::new();
for key in state_sets.iter().flat_map(|map| map.keys()).unique() { for key in state_sets_iter.clone().flat_map(|map| map.keys()).unique() {
let mut event_ids = let mut event_ids =
state_sets.iter().map(|state_set| state_set.get(key)).collect::<Vec<_>>(); state_sets_iter.clone().map(|state_set| state_set.get(key)).collect::<Vec<_>>();
if event_ids.iter().all_equal() { if event_ids.iter().all_equal() {
// First .unwrap() is okay because // First .unwrap() is okay because
@ -975,7 +976,7 @@ mod tests {
let (state_at_bob, state_at_charlie, expected) = store.set_up(); let (state_at_bob, state_at_charlie, expected) = store.set_up();
let ev_map: EventMap<Arc<StateEvent>> = store.0.clone(); let ev_map: EventMap<Arc<StateEvent>> = store.0.clone();
let state_sets = vec![state_at_bob, state_at_charlie]; let state_sets = [state_at_bob, state_at_charlie];
let resolved = match crate::resolve( let resolved = match crate::resolve(
&RoomVersionId::Version2, &RoomVersionId::Version2,
&state_sets, &state_sets,
@ -1079,7 +1080,7 @@ mod tests {
.collect::<StateMap<_>>(); .collect::<StateMap<_>>();
let ev_map: EventMap<Arc<StateEvent>> = store.0.clone(); let ev_map: EventMap<Arc<StateEvent>> = store.0.clone();
let state_sets = vec![state_set_a, state_set_b]; let state_sets = [state_set_a, state_set_b];
let resolved = match crate::resolve( let resolved = match crate::resolve(
&RoomVersionId::Version6, &RoomVersionId::Version6,
&state_sets, &state_sets,

View File

@ -89,11 +89,8 @@ pub fn do_check(
} else if prev_events.len() == 1 { } else if prev_events.len() == 1 {
state_at_event.get(prev_events.iter().next().unwrap()).unwrap().clone() state_at_event.get(prev_events.iter().next().unwrap()).unwrap().clone()
} else { } else {
let state_sets = prev_events let state_sets =
.iter() prev_events.iter().filter_map(|k| state_at_event.get(k)).collect::<Vec<_>>();
.filter_map(|k| state_at_event.get(k))
.cloned()
.collect::<Vec<_>>();
info!( info!(
"{:#?}", "{:#?}",
@ -106,17 +103,17 @@ pub fn do_check(
.collect::<Vec<_>>() .collect::<Vec<_>>()
); );
let resolved = crate::resolve( let auth_chain_sets = state_sets
&RoomVersionId::Version6,
&state_sets,
state_sets
.iter() .iter()
.map(|map| { .map(|map| {
store.auth_event_ids(&room_id(), map.values().cloned().collect()).unwrap() store.auth_event_ids(&room_id(), map.values().cloned().collect()).unwrap()
}) })
.collect(), .collect();
|id| event_map.get(id).map(Arc::clone),
); let resolved =
crate::resolve(&RoomVersionId::Version6, state_sets, auth_chain_sets, |id| {
event_map.get(id).map(Arc::clone)
});
match resolved { match resolved {
Ok(state) => state, Ok(state) => state,
Err(e) => panic!("resolution for {} failed: {}", node, e), Err(e) => panic!("resolution for {} failed: {}", node, e),