This repository was archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Consistently compare to the earliest known stream position in the stream change cache #14435
Merged
Merged
Changes from 5 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
64dc954
Add (failing) tests.
clokep c969ab4
Use strict comparisons in stream change cache.
clokep 3a46941
Newsfragment
clokep f0dbf31
Update asserts.
clokep 7d0e07f
Clarify comments.
clokep 9842054
Use peek instead of bisect.
clokep 0c6c603
Clarify code & comments.
clokep e2e4f37
Improve docstrings.
clokep 532f69a
Update tests for changes.
clokep dff4b5c
Merge branch 'develop' into clokep/stream-cache-fix
clokep 6b09889
Bump min sortedcontainers version.
clokep f0634bf
Merge remote-tracking branch 'origin/develop' into clokep/stream-cach…
clokep d3513a3
Fix poetry lock.
clokep ae77f8b
Newsfragment
clokep 53cd4cc
Add a comment.
clokep 865792a
Merge remote-tracking branch 'origin/develop' into clokep/stream-cach…
clokep File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Fix. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,10 +45,13 @@ def __init__( | |
| ) -> None: | ||
| self._original_max_size: int = max_size | ||
| self._max_size = math.floor(max_size) | ||
| self._entity_to_key: Dict[EntityType, int] = {} | ||
|
|
||
| # map from stream id to the a set of entities which changed at that stream id. | ||
| # map from stream id to the set of entities which changed at that stream id. | ||
| self._cache: SortedDict[int, Set[EntityType]] = SortedDict() | ||
| # map from entity to the stream ID of the latest change for that entity. | ||
| # | ||
| # Must be kept in sync with _cache. | ||
| self._entity_to_key: Dict[EntityType, int] = {} | ||
|
|
||
| # the earliest stream_pos for which we can reliably answer | ||
| # get_all_entities_changed. In other words, one less than the earliest | ||
|
|
@@ -85,35 +88,44 @@ def has_entity_changed(self, entity: EntityType, stream_pos: int) -> bool: | |
| """Returns True if the entity may have been updated since stream_pos""" | ||
| assert isinstance(stream_pos, int) | ||
|
|
||
| if stream_pos < self._earliest_known_stream_pos: | ||
| # _cache is not valid at or before the earliest known stream position, so | ||
| # return that the entity has changed. | ||
| if stream_pos <= self._earliest_known_stream_pos: | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| self.metrics.inc_misses() | ||
| return True | ||
|
|
||
| # If the entity is unknown, it hasn't changed. | ||
| latest_entity_change_pos = self._entity_to_key.get(entity, None) | ||
| if latest_entity_change_pos is None: | ||
| self.metrics.inc_hits() | ||
| return False | ||
|
|
||
| # This is a known entity, return true if the stream position is earlier | ||
| # than the last change. | ||
| if stream_pos < latest_entity_change_pos: | ||
| self.metrics.inc_misses() | ||
| return True | ||
|
|
||
| # Otherwise, the stream position is after the latest change: return false. | ||
| self.metrics.inc_hits() | ||
| return False | ||
|
|
||
| def get_entities_changed( | ||
| 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. | ||
| Returns the subset of given entities that have had changes 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: | ||
| # 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 | ||
| # given iterable is already a 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)): | ||
|
|
@@ -130,8 +142,8 @@ def get_entities_changed( | |
| return result | ||
|
|
||
| def has_any_entity_changed(self, stream_pos: int) -> bool: | ||
| """Returns if any entity has changed""" | ||
| assert type(stream_pos) is int | ||
| """Returns true if any entity has changed""" | ||
| assert isinstance(stream_pos, int) | ||
|
|
||
| if not self._cache: | ||
| # If the cache is empty, nothing can have changed. | ||
|
|
@@ -145,13 +157,15 @@ def has_any_entity_changed(self, stream_pos: int) -> bool: | |
| return True | ||
|
|
||
| def get_all_entities_changed(self, stream_pos: int) -> Optional[List[EntityType]]: | ||
| """Returns all entities that have had new things since the given | ||
| """Returns all entities that have had changes since the given | ||
| position. If the position is too old it will return None. | ||
|
|
||
| Returns the entities in the order that they were changed. | ||
| """ | ||
| assert type(stream_pos) is int | ||
| assert isinstance(stream_pos, int) | ||
|
|
||
| # _cache is not valid before the earliest known stream position, so | ||
| # return that no known entities have changed. | ||
| if stream_pos < self._earliest_known_stream_pos: | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return None | ||
|
|
||
|
|
@@ -165,8 +179,10 @@ def entity_has_changed(self, entity: EntityType, stream_pos: int) -> None: | |
| """Informs the cache that the entity has been changed at the given | ||
| position. | ||
| """ | ||
| assert type(stream_pos) is int | ||
| assert isinstance(stream_pos, int) | ||
|
|
||
| # For a change before _cache is valid (e.g. at or before the earliest known | ||
| # stream position) there's nothing to do. | ||
| if stream_pos <= self._earliest_known_stream_pos: | ||
| return | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.