Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit b26f3e5

Browse files
authored
Merge pull request #7423 from matrix-org/erikj/faster_device_lists_fetch
Speed up fetching device lists changes in sync.
2 parents c255b0f + 13dd458 commit b26f3e5

File tree

4 files changed

+26
-10
lines changed

4 files changed

+26
-10
lines changed

changelog.d/7423.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Speed up fetching device lists changes when handling `/sync` requests.

synapse/handlers/sync.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,10 +1143,14 @@ async def _generate_sync_entry_for_device_list(
11431143
user_id
11441144
)
11451145

1146-
tracked_users = set(users_who_share_room)
1147-
1148-
# Always tell the user about their own devices
1149-
tracked_users.add(user_id)
1146+
# Always tell the user about their own devices. We check as the user
1147+
# ID is almost certainly already included (unless they're not in any
1148+
# rooms) and taking a copy of the set is relatively expensive.
1149+
if user_id not in users_who_share_room:
1150+
users_who_share_room = set(users_who_share_room)
1151+
users_who_share_room.add(user_id)
1152+
1153+
tracked_users = users_who_share_room
11501154

11511155
# Step 1a, check for changes in devices of users we share a room with
11521156
users_that_have_changed = await self.store.get_users_whose_devices_changed(

synapse/storage/data_stores/main/devices.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,8 @@ def get_users_whose_devices_changed(self, from_key, user_ids):
541541

542542
# Get set of users who *may* have changed. Users not in the returned
543543
# list have definitely not changed.
544-
to_check = list(
545-
self._device_list_stream_cache.get_entities_changed(user_ids, from_key)
544+
to_check = self._device_list_stream_cache.get_entities_changed(
545+
user_ids, from_key
546546
)
547547

548548
if not to_check:

synapse/util/caches/stream_change_cache.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
# limitations under the License.
1515

1616
import logging
17-
from typing import Dict, Iterable, List, Mapping, Optional, Set
17+
from typing import Dict, FrozenSet, List, Mapping, Optional, Set, Union
1818

1919
from six import integer_types
2020

2121
from sortedcontainers import SortedDict
2222

23+
from synapse.types import Collection
2324
from synapse.util import caches
2425

2526
logger = logging.getLogger(__name__)
@@ -85,16 +86,26 @@ def has_entity_changed(self, entity: EntityType, stream_pos: int) -> bool:
8586
return False
8687

8788
def get_entities_changed(
88-
self, entities: Iterable[EntityType], stream_pos: int
89-
) -> Set[EntityType]:
89+
self, entities: Collection[EntityType], stream_pos: int
90+
) -> Union[Set[EntityType], FrozenSet[EntityType]]:
9091
"""
9192
Returns subset of entities that have had new things since the given
9293
position. Entities unknown to the cache will be returned. If the
9394
position is too old it will just return the given list.
9495
"""
9596
changed_entities = self.get_all_entities_changed(stream_pos)
9697
if changed_entities is not None:
97-
result = set(changed_entities).intersection(entities)
98+
# We now do an intersection, trying to do so in the most efficient
99+
# way possible (some of these sets are *large*). First check in the
100+
# given iterable is already set that we can reuse, otherwise we
101+
# create a set of the *smallest* of the two iterables and call
102+
# `intersection(..)` on it (this can be twice as fast as the reverse).
103+
if isinstance(entities, (set, frozenset)):
104+
result = entities.intersection(changed_entities)
105+
elif len(changed_entities) < len(entities):
106+
result = set(changed_entities).intersection(entities)
107+
else:
108+
result = set(entities).intersection(changed_entities)
98109
self.metrics.inc_hits()
99110
else:
100111
result = set(entities)

0 commit comments

Comments
 (0)