refactor: one upstream name index for core lookups

This commit is contained in:
Abdessamad Derraz committed 2026-10-06 01:47:16 +02:00
1 parent 994836938c
commit ca86236c12
6 files changed
+121 -42

No files matched your search

+14 -11
View File
@@ -54,6 +54,7 @@ import upstream # noqa: E402
from common import ( # noqa: E402
list_registered_platforms,
load_emulator_profiles,
upstream_profile_index,
yaml_load,
)
from exporter import discover_exporters # noqa: E402
@@ -364,14 +365,9 @@ def check_native(platforms_dir: Path, cache_dir: Path, truth_dir: Path) -> list[
# --- targets ----------------------------------------------------------------
def profile_name_index(profiles: dict[str, dict]) -> dict[str, str]:
"""Upstream core name -> profile key, the index target filtering uses."""
index: dict[str, str] = {}
for key, profile in profiles.items():
index.setdefault(key, key)
for alias in profile.get("cores") or []:
index.setdefault(str(alias), key)
return index
def profile_name_index(profiles: dict[str, dict]) -> dict[str, set[str]]:
"""Upstream core name -> the profiles that claim it, as target filtering reads it."""
return upstream_profile_index(profiles, include_aliases=True)
def _removed_cores(overrides: dict, platform: str) -> dict[str, set[str]]:
@@ -539,13 +535,20 @@ def coreinfo_gaps(
Matching folds case: the buildbot serves lower-case names while a few
.info files keep the project's own casing.
"""
index = {k.casefold(): v for k, v in profile_name_index(profiles).items()}
index: dict[str, set[str]] = {}
for key, claimants in profile_name_index(profiles).items():
index.setdefault(key.casefold(), set()).update(claimants)
unprofiled = [n for n in names if n.casefold() not in index]
# A name only standalone profiles claim: libretro now builds a core
# nothing in the collection describes as one.
standalone = [
(n, index[n.casefold()])
(n, sorted(index[n.casefold()])[0])
for n in names
if n.casefold() in index
and str(profiles[index[n.casefold()]].get("type", "")).strip() == "standalone"
and all(
str(profiles[c].get("type", "")).strip() == "standalone"
for c in index[n.casefold()]
)
]
return unprofiled, standalone
+44 -21
View File
@@ -1298,6 +1298,36 @@ def runs_standalone(
)
def upstream_profile_index(
profiles: dict[str, dict], include_aliases: bool = False
) -> dict[str, set[str]]:
"""Every name a core is known by upstream -> the profiles that claim it.
A name can be claimed twice: the buildbot's `pcsx2` is the LRPS2 core,
which lrps2.yml lists in `cores:`, and also the key of the standalone
pcsx2 profile. A last-wins dict kept one of the two depending on file
order, and a RetroArch target filter dropped LRPS2's files. Callers
choose: a platform list prefers the exact key, a target filter keeps
every claimant.
"""
index: dict[str, set[str]] = {}
for name, profile in profiles.items():
if not include_aliases and profile.get("type") == "alias":
continue
index.setdefault(name, set()).add(name)
for core in profile.get("cores") or []:
index.setdefault(str(core), set()).add(name)
return index
def preferred_profile(index: dict[str, set[str]], name: str) -> str | None:
"""The profile a name designates: its own key first, else the first claimant."""
claimants = index.get(name)
if not claimants:
return None
return name if name in claimants else sorted(claimants)[0]
def resolve_platform_cores(
config: dict,
profiles: dict[str, dict],
@@ -1323,14 +1353,12 @@ def resolve_platform_cores(
}
elif isinstance(cores_config, list):
core_set = {str(c) for c in cores_config}
core_to_profile: dict[str, str] = {}
for name, p in profiles.items():
if p.get("type") == "alias":
continue
core_to_profile[name] = name
for core_name in p.get("cores", []):
core_to_profile[str(core_name)] = name
result = {core_to_profile[c] for c in core_set if c in core_to_profile}
index = upstream_profile_index(profiles)
result = {
profile
for c in core_set
if (profile := preferred_profile(index, c)) is not None
}
# Support "all_libretro" as a list element: combines all libretro
# profiles with explicitly listed standalone cores (e.g. RetroDECK
# ships RetroArch + standalone emulators)
@@ -1355,13 +1383,10 @@ def resolve_platform_cores(
# Upstream sources (buildbot, es_systems) may use different names
# than our profile keys (e.g., mednafen_psx vs beetle_psx).
# The profiles' cores: field lists these alternate names.
upstream_to_profile: dict[str, str] = {}
for name, p in profiles.items():
upstream_to_profile[name] = name
for alias in p.get("cores", []):
upstream_to_profile[str(alias)] = name
# Expand target_cores to profile keys
expanded = {upstream_to_profile.get(c, c) for c in target_cores}
index = upstream_profile_index(profiles, include_aliases=True)
expanded = {
profile for c in target_cores for profile in index.get(c, {c})
}
result = result & expanded
return result
@@ -1467,12 +1492,10 @@ def filter_systems_by_target(
return systems
# Build reverse index for target core name resolution
upstream_to_profile: dict[str, str] = {}
for name, p in profiles.items():
upstream_to_profile[name] = name
for alias in p.get("cores", []):
upstream_to_profile[str(alias)] = name
expanded_target = {upstream_to_profile.get(c, c) for c in target_cores}
index = upstream_profile_index(profiles, include_aliases=True)
expanded_target = {
profile for c in target_cores for profile in index.get(c, {c})
}
_norm_sid = _norm_system_id
+7 -5
View File
@@ -38,8 +38,10 @@ from common import (
load_emulator_profiles,
load_provenance_snapshots,
parse_md5_list,
preferred_profile,
require_yaml,
unique_emulator_profiles,
upstream_profile_index,
write_if_changed as _write_artifact,
yaml_load,
)
@@ -3116,11 +3118,11 @@ def generate_cross_reference(
k: v for k, v in profiles.items() if v.get("type") not in ("alias", "test")
}
# Build core -> profile lookup by core name
core_to_profile: dict[str, str] = {}
for pname, p in unique.items():
for core in p.get("cores", [pname]):
core_to_profile[str(core)] = pname
# Core name -> the profile it designates, the rule target filtering uses.
index = upstream_profile_index(unique)
core_to_profile: dict[str, str] = {
core: preferred_profile(index, core) for core in index
}
total_cores = len(unique)
total_upstreams = len({