-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Speed up fetching device lists changes in sync. #7423
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Speed up fetching device lists changes when handling `/sync` requests. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,12 +14,13 @@ | |
| # limitations under the License. | ||
|
|
||
| import logging | ||
| from typing import Dict, Iterable, List, Mapping, Optional, Set | ||
| from typing import Dict, FrozenSet, List, Mapping, Optional, Set, Union | ||
|
|
||
| from six import integer_types | ||
|
|
||
| from sortedcontainers import SortedDict | ||
|
|
||
| from synapse.types import Collection | ||
| from synapse.util import caches | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
@@ -85,16 +86,26 @@ def has_entity_changed(self, entity: EntityType, stream_pos: int) -> bool: | |
| return False | ||
|
|
||
| def get_entities_changed( | ||
| self, entities: Iterable[EntityType], stream_pos: int | ||
| ) -> Set[EntityType]: | ||
| self, entities: Collection[EntityType], stream_pos: int | ||
| ) -> Union[Set[EntityType], FrozenSet[EntityType]]: | ||
| """ | ||
| Returns subset of entities that have had new things since the given | ||
| position. Entities unknown to the cache will be returned. If the | ||
| position is too old it will just return the given list. | ||
| """ | ||
| changed_entities = self.get_all_entities_changed(stream_pos) | ||
| if changed_entities is not None: | ||
| result = set(changed_entities).intersection(entities) | ||
| # We now do an intersection, trying to do so in the most efficient | ||
| # way possible (some of these sets are *large*). First check in the | ||
| # given iterable is already set that we can reuse, otherwise we | ||
| # create a set of the *smallest* of the two iterables and call | ||
| # `intersection(..)` on it (this can be twice as fast as the reverse). | ||
|
||
| if isinstance(entities, (set, frozenset)): | ||
| result = entities.intersection(changed_entities) | ||
| elif len(changed_entities) < len(entities): | ||
| result = set(changed_entities).intersection(entities) | ||
| else: | ||
| result = set(entities).intersection(changed_entities) | ||
| self.metrics.inc_hits() | ||
| else: | ||
| result = set(entities) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked all the callers and this matches their types fwiw