diff --git a/app/logic/game_support.py b/app/logic/game_support.py index da2489ef..1fec9e34 100644 --- a/app/logic/game_support.py +++ b/app/logic/game_support.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from typing import List, Dict, Optional +from typing import List, Dict, Optional, Tuple import sqlalchemy @@ -93,10 +93,12 @@ class GSPackage: class GameSupport: packages: Dict[str, GSPackage] modified_packages: set[GSPackage] + dependency_cache: Dict[str, Tuple[Optional[bool], Optional[set[str]]]] def __init__(self): self.packages = {} self.modified_packages = set() + self.dependency_cache = {} @property def all_confirmed(self): @@ -135,6 +137,10 @@ class GameSupport: dep_supports_all = False for_dep = set() + if depend in self.dependency_cache: + dep_supports_all, for_dep = self.dependency_cache[depend] + return dep_supports_all, for_dep + for provider in self.get_all_that_provide(depend): found_in = self._get_supported_games(provider, visited) if found_in is None: @@ -146,6 +152,7 @@ class GameSupport: else: for_dep.update(found_in) + self.dependency_cache[depend] = (dep_supports_all, for_dep) return dep_supports_all, for_dep def _get_supported_games_for_deps(self, package: GSPackage, visited: list[str]) -> Optional[set[str]]: @@ -214,6 +221,7 @@ class GameSupport: return package.supported_games def on_update(self, package: GSPackage, old_provides: Optional[set[str]] = None): + self.dependency_cache = {} to_update = {package} checked = set() @@ -235,10 +243,12 @@ class GameSupport: checked.add(depending_package) def on_remove(self, package: GSPackage): + self.dependency_cache = {} del self.packages[package.id_] self.on_update(package) def on_first_run(self): + self.dependency_cache = {} for package in self.packages.values(): if not package.is_confirmed: self.on_update(package) diff --git a/app/tests/unit/logic/test_game_support.py b/app/tests/unit/logic/test_game_support.py index a657635f..70d02dad 100644 --- a/app/tests/unit/logic/test_game_support.py +++ b/app/tests/unit/logic/test_game_support.py @@ -204,11 +204,9 @@ def test_cycle(): support.on_update(modA) assert support.all_errors == { - "author/mod_a: Dependency cycle detected: author/mod_b -> author/mod_a -> author/mod_b", "author/mod_b: Dependency cycle detected: author/mod_a -> author/mod_b -> author/mod_a", "author/mod_a: Dependency cycle detected: author/mod_a -> author/mod_b -> author/mod_a", "author/mod_b: Unable to fulfill dependency mod_a", - "author/mod_b: Dependency cycle detected: author/mod_b -> author/mod_a -> author/mod_b", "author/mod_a: Unable to fulfill dependency mod_b" } @@ -377,9 +375,7 @@ def test_update_cycle(): assert support.all_errors == { "author/mod_c: Dependency cycle detected: author/mod_a -> author/mod_c -> author/mod_a", "author/mod_a: Dependency cycle detected: author/mod_a -> author/mod_c -> author/mod_a", - "author/mod_a: Dependency cycle detected: author/mod_c -> author/mod_a -> author/mod_c", "author/mod_a: Unable to fulfill dependency mod_c", - "author/mod_c: Dependency cycle detected: author/mod_c -> author/mod_a -> author/mod_c", "author/mod_c: Unable to fulfill dependency mod_a" }