mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-22 22:12:24 +01:00
Add dependency-based cache to game support algorithm
This commit is contained in:
parent
b33a7f79b1
commit
a8d2cc0383
@ -14,7 +14,7 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from typing import List, Dict, Optional
|
from typing import List, Dict, Optional, Tuple
|
||||||
|
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
|
||||||
@ -93,10 +93,12 @@ class GSPackage:
|
|||||||
class GameSupport:
|
class GameSupport:
|
||||||
packages: Dict[str, GSPackage]
|
packages: Dict[str, GSPackage]
|
||||||
modified_packages: set[GSPackage]
|
modified_packages: set[GSPackage]
|
||||||
|
dependency_cache: Dict[str, Tuple[Optional[bool], Optional[set[str]]]]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.packages = {}
|
self.packages = {}
|
||||||
self.modified_packages = set()
|
self.modified_packages = set()
|
||||||
|
self.dependency_cache = {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def all_confirmed(self):
|
def all_confirmed(self):
|
||||||
@ -135,6 +137,10 @@ class GameSupport:
|
|||||||
dep_supports_all = False
|
dep_supports_all = False
|
||||||
for_dep = set()
|
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):
|
for provider in self.get_all_that_provide(depend):
|
||||||
found_in = self._get_supported_games(provider, visited)
|
found_in = self._get_supported_games(provider, visited)
|
||||||
if found_in is None:
|
if found_in is None:
|
||||||
@ -146,6 +152,7 @@ class GameSupport:
|
|||||||
else:
|
else:
|
||||||
for_dep.update(found_in)
|
for_dep.update(found_in)
|
||||||
|
|
||||||
|
self.dependency_cache[depend] = (dep_supports_all, for_dep)
|
||||||
return 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]]:
|
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
|
return package.supported_games
|
||||||
|
|
||||||
def on_update(self, package: GSPackage, old_provides: Optional[set[str]] = None):
|
def on_update(self, package: GSPackage, old_provides: Optional[set[str]] = None):
|
||||||
|
self.dependency_cache = {}
|
||||||
to_update = {package}
|
to_update = {package}
|
||||||
checked = set()
|
checked = set()
|
||||||
|
|
||||||
@ -235,10 +243,12 @@ class GameSupport:
|
|||||||
checked.add(depending_package)
|
checked.add(depending_package)
|
||||||
|
|
||||||
def on_remove(self, package: GSPackage):
|
def on_remove(self, package: GSPackage):
|
||||||
|
self.dependency_cache = {}
|
||||||
del self.packages[package.id_]
|
del self.packages[package.id_]
|
||||||
self.on_update(package)
|
self.on_update(package)
|
||||||
|
|
||||||
def on_first_run(self):
|
def on_first_run(self):
|
||||||
|
self.dependency_cache = {}
|
||||||
for package in self.packages.values():
|
for package in self.packages.values():
|
||||||
if not package.is_confirmed:
|
if not package.is_confirmed:
|
||||||
self.on_update(package)
|
self.on_update(package)
|
||||||
|
@ -204,11 +204,9 @@ def test_cycle():
|
|||||||
support.on_update(modA)
|
support.on_update(modA)
|
||||||
|
|
||||||
assert support.all_errors == {
|
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_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_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: 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"
|
"author/mod_a: Unable to fulfill dependency mod_b"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,9 +375,7 @@ def test_update_cycle():
|
|||||||
assert support.all_errors == {
|
assert support.all_errors == {
|
||||||
"author/mod_c: Dependency cycle detected: author/mod_a -> author/mod_c -> author/mod_a",
|
"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_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_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"
|
"author/mod_c: Unable to fulfill dependency mod_a"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user