Short circuit if all new events have same state group

pull/2070/head
Erik Johnston 2017-03-27 18:00:47 +01:00
parent 281553afe6
commit d82c42837f
1 changed files with 49 additions and 34 deletions

View File

@ -428,6 +428,7 @@ class EventsStore(SQLBaseStore):
# Now we need to work out the different state sets for # Now we need to work out the different state sets for
# each state extremities # each state extremities
state_sets = [] state_sets = []
state_groups = set()
missing_event_ids = [] missing_event_ids = []
was_updated = False was_updated = False
for event_id in new_latest_event_ids: for event_id in new_latest_event_ids:
@ -437,9 +438,17 @@ class EventsStore(SQLBaseStore):
if event_id == ev.event_id: if event_id == ev.event_id:
if ctx.current_state_ids is None: if ctx.current_state_ids is None:
raise Exception("Unknown current state") raise Exception("Unknown current state")
state_sets.append(ctx.current_state_ids)
if ctx.delta_ids or hasattr(ev, "state_key"): # If we've akready seen the state group don't bother adding
was_updated = True # it to the state sets again
if ctx.state_group not in state_groups:
state_sets.append(ctx.current_state_ids)
if ctx.delta_ids or hasattr(ev, "state_key"):
was_updated = True
if ctx.state_group:
# Add this as a seen state group (if it has a state
# group)
state_groups.add(ctx.state_group)
break break
else: else:
# If we couldn't find it, then we'll need to pull # If we couldn't find it, then we'll need to pull
@ -453,45 +462,51 @@ class EventsStore(SQLBaseStore):
missing_event_ids, missing_event_ids,
) )
groups = set(event_to_groups.itervalues()) groups = set(event_to_groups.itervalues()) - state_groups
group_to_state = yield self._get_state_for_groups(groups)
state_sets.extend(group_to_state.itervalues()) if groups:
group_to_state = yield self._get_state_for_groups(groups)
state_sets.extend(group_to_state.itervalues())
if not new_latest_event_ids: if not new_latest_event_ids:
current_state = {} current_state = {}
elif was_updated: elif was_updated:
# We work out the current state by passing the state sets to the if len(state_sets) == 1:
# state resolution algorithm. It may ask for some events, including # If there is only one state set, then we know what the current
# the events we have yet to persist, so we need a slightly more # state is.
# complicated event lookup function than simply looking the events current_state = state_sets[0]
# up in the db. else:
events_map = {ev.event_id: ev for ev, _ in events_context} # We work out the current state by passing the state sets to the
# state resolution algorithm. It may ask for some events, including
# the events we have yet to persist, so we need a slightly more
# complicated event lookup function than simply looking the events
# up in the db.
events_map = {ev.event_id: ev for ev, _ in events_context}
@defer.inlineCallbacks @defer.inlineCallbacks
def get_events(ev_ids): def get_events(ev_ids):
# We get the events by first looking at the list of events we # We get the events by first looking at the list of events we
# are trying to persist, and then fetching the rest from the DB. # are trying to persist, and then fetching the rest from the DB.
db = [] db = []
to_return = {} to_return = {}
for ev_id in ev_ids: for ev_id in ev_ids:
ev = events_map.get(ev_id, None) ev = events_map.get(ev_id, None)
if ev: if ev:
to_return[ev_id] = ev to_return[ev_id] = ev
else: else:
db.append(ev_id) db.append(ev_id)
if db: if db:
evs = yield self.get_events( evs = yield self.get_events(
ev_ids, get_prev_content=False, check_redacted=False, ev_ids, get_prev_content=False, check_redacted=False,
) )
to_return.update(evs) to_return.update(evs)
defer.returnValue(to_return) defer.returnValue(to_return)
current_state = yield resolve_events( current_state = yield resolve_events(
state_sets, state_sets,
state_map_factory=get_events, state_map_factory=get_events,
) )
else: else:
return return