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

Commit 880aa99

Browse files
committed
Minor optimisation to cachedListDescriptor
we can avoid re-using `missing`, which saves looking up entries in `deferreds_map`, and means we don't need to copy it.
1 parent e4c46c1 commit 880aa99

File tree

2 files changed

+11
-13
lines changed

2 files changed

+11
-13
lines changed

synapse/util/caches/descriptors.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -346,10 +346,10 @@ class DeferredCacheListDescriptor(_CacheDescriptorBase):
346346
"""Wraps an existing cache to support bulk fetching of keys.
347347
348348
Given an iterable of keys it looks in the cache to find any hits, then passes
349-
the tuple of missing keys to the wrapped function.
349+
the set of missing keys to the wrapped function.
350350
351-
Once wrapped, the function returns a Deferred which resolves to the list
352-
of results.
351+
Once wrapped, the function returns a Deferred which resolves to a Dict mapping from
352+
input key to output value.
353353
"""
354354

355355
def __init__(
@@ -452,14 +452,14 @@ def complete_all(res: Dict[Hashable, Any]) -> None:
452452
# the wrapped function has completed. It returns a dict.
453453
# We can now update our own result map, and then resolve the
454454
# observable deferreds in the cache.
455-
for e in missing:
455+
for e, d1 in deferreds_map.items():
456456
val = res.get(e, None)
457457
# make sure we update the results map before running the
458458
# deferreds, because as soon as we run the last deferred, the
459459
# gatherResults() below will complete and return the result
460460
# dict to our caller.
461461
results[e] = val
462-
deferreds_map[e].callback(val)
462+
d1.callback(val)
463463

464464
def errback_all(f: Failure) -> None:
465465
# the wrapped function has failed. Propagate the failure into
@@ -470,9 +470,7 @@ def errback_all(f: Failure) -> None:
470470
d1.errback(f)
471471

472472
args_to_call = dict(arg_dict)
473-
# copy the missing set before sending it to the callee, to guard against
474-
# modification.
475-
args_to_call[self.list_name] = tuple(missing)
473+
args_to_call[self.list_name] = missing
476474

477475
# dispatch the call, and attach the two handlers
478476
defer.maybeDeferred(

tests/util/caches/test_descriptors.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -673,14 +673,14 @@ async def list_fn(self, args1, arg2):
673673
self.assertEqual(current_context(), SENTINEL_CONTEXT)
674674
r = yield d1
675675
self.assertEqual(current_context(), c1)
676-
obj.mock.assert_called_once_with((10, 20), 2)
676+
obj.mock.assert_called_once_with({10, 20}, 2)
677677
self.assertEqual(r, {10: "fish", 20: "chips"})
678678
obj.mock.reset_mock()
679679

680680
# a call with different params should call the mock again
681681
obj.mock.return_value = {30: "peas"}
682682
r = yield obj.list_fn([20, 30], 2)
683-
obj.mock.assert_called_once_with((30,), 2)
683+
obj.mock.assert_called_once_with({30}, 2)
684684
self.assertEqual(r, {20: "chips", 30: "peas"})
685685
obj.mock.reset_mock()
686686

@@ -701,7 +701,7 @@ async def list_fn(self, args1, arg2):
701701
obj.mock.return_value = {40: "gravy"}
702702
iterable = (x for x in [10, 40, 40])
703703
r = yield obj.list_fn(iterable, 2)
704-
obj.mock.assert_called_once_with((40,), 2)
704+
obj.mock.assert_called_once_with({40}, 2)
705705
self.assertEqual(r, {10: "fish", 40: "gravy"})
706706

707707
def test_concurrent_lookups(self):
@@ -729,7 +729,7 @@ def list_fn(self, args1) -> "Deferred[dict]":
729729
d3 = obj.list_fn([10])
730730

731731
# the mock should have been called exactly once
732-
obj.mock.assert_called_once_with((10,))
732+
obj.mock.assert_called_once_with({10})
733733
obj.mock.reset_mock()
734734

735735
# ... and none of the calls should yet be complete
@@ -771,7 +771,7 @@ async def list_fn(self, args1, arg2):
771771
# cache miss
772772
obj.mock.return_value = {10: "fish", 20: "chips"}
773773
r1 = yield obj.list_fn([10, 20], 2, on_invalidate=invalidate0)
774-
obj.mock.assert_called_once_with((10, 20), 2)
774+
obj.mock.assert_called_once_with({10, 20}, 2)
775775
self.assertEqual(r1, {10: "fish", 20: "chips"})
776776
obj.mock.reset_mock()
777777

0 commit comments

Comments
 (0)