diff --git a/backend/endpoints/sockets/scan.py b/backend/endpoints/sockets/scan.py index 0c326ecbf..da84c59f7 100644 --- a/backend/endpoints/sockets/scan.py +++ b/backend/endpoints/sockets/scan.py @@ -451,7 +451,6 @@ async def _identify_platform( socket_manager: socketio.AsyncRedisManager, scan_stats: ScanStats, calculate_hashes: bool = True, - fs_roms_cache: dict[str, list[FSRom]] | None = None, ) -> ScanStats: # Stop the scan if the flag is set if redis_client.get(STOP_SCAN_FLAG): @@ -520,15 +519,11 @@ async def _identify_platform( new_firmware=new_firmware, ) - # Use cached filesystem data if available - if fs_roms_cache is not None and platform_slug in fs_roms_cache: - fs_roms = fs_roms_cache[platform_slug] - else: - try: - fs_roms = await fs_rom_handler.get_roms(platform) - except RomsNotFoundException as e: - log.error(e) - return scan_stats + try: + fs_roms = await fs_rom_handler.get_roms(platform) + except RomsNotFoundException as e: + log.error(e) + return scan_stats if len(fs_roms) == 0: log.warning( @@ -657,15 +652,12 @@ async def scan_platforms( if MetadataSource.HLTB in metadata_sources: meta_hltb_handler.initialize() - # Precalculate total platforms and ROMs, caching filesystem reads - # so _identify_platform() doesn't have to re-read the same directories - fs_roms_cache: dict[str, list[FSRom]] = {} total_roms = 0 for platform_slug in fs_platforms: try: - fs_roms = await fs_rom_handler.get_roms(Platform(fs_slug=platform_slug)) - fs_roms_cache[platform_slug] = fs_roms - total_roms += len(fs_roms) + total_roms += await fs_rom_handler.count_roms( + Platform(fs_slug=platform_slug) + ) except RomsNotFoundException as e: log.error(e) @@ -709,7 +701,6 @@ async def scan_platforms( socket_manager=socket_manager, scan_stats=scan_stats, calculate_hashes=calculate_hashes, - fs_roms_cache=fs_roms_cache, ) missed_platforms = db_platform_handler.mark_missing_platforms(fs_platforms) diff --git a/backend/handler/filesystem/roms_handler.py b/backend/handler/filesystem/roms_handler.py index 4e2079e3d..c4ee773c7 100644 --- a/backend/handler/filesystem/roms_handler.py +++ b/backend/handler/filesystem/roms_handler.py @@ -680,6 +680,21 @@ class FSRomsHandler(FSHandler): rom_sha1_h, ) + async def count_roms(self, platform: Platform) -> int: + """Return the number of filesystem roms for a platform without + materializing FSRom objects. + """ + try: + rel_roms_path = self.get_roms_fs_structure(platform.fs_slug) + fs_single_roms = await self.list_files(path=rel_roms_path) + fs_multi_roms = await self.list_directories(path=rel_roms_path) + except FileNotFoundError as e: + raise RomsNotFoundException(platform=platform.fs_slug) from e + + return len(self.exclude_single_files(fs_single_roms)) + len( + self.exclude_multi_roms(fs_multi_roms) + ) + async def get_roms(self, platform: Platform) -> list[FSRom]: """Gets all filesystem roms for a platform diff --git a/backend/tests/handler/test_db_handler.py b/backend/tests/handler/test_db_handler.py index 049529959..df1389a4d 100644 --- a/backend/tests/handler/test_db_handler.py +++ b/backend/tests/handler/test_db_handler.py @@ -506,7 +506,7 @@ def test_mark_missing_roms_large_platform(platform: Platform): ) ) - # Build a keep list with >500 entries to trigger the flip-based path. + # Build a large keep list to verify mark_missing_roms() handles many entries. # Only rom_present.zip actually exists in DB; the rest are just filler. fs_roms_to_keep = ["rom_present.zip"] + [f"filler_{i}.zip" for i in range(501)]