diff --git a/scripts/packextras.py b/scripts/packextras.py index 6c65f70d..773dd501 100644 --- a/scripts/packextras.py +++ b/scripts/packextras.py @@ -446,12 +446,28 @@ def _companions( wanted |= {f"{stem}.{ext}" for ext in extensions} return sorted( (sha1, entry) - for sha1, entry in files_db.items() - if entry.get("path", "").rsplit("/", 1)[0] + "/" == directory - and str(entry.get("name", "")).lower() in wanted + for sha1, entry in _files_by_directory(files_db).get(directory, ()) + if str(entry.get("name", "")).lower() in wanted ) +# The database a directory index was built from, with the index: one walk +# per database instead of one per scanned image (1 023 walks of 19 041 +# entries in verify --all). +_DIRECTORY_INDEX: tuple[dict, dict[str, list[tuple[str, dict]]]] | None = None + + +def _files_by_directory(files_db: dict) -> dict[str, list[tuple[str, dict]]]: + global _DIRECTORY_INDEX + if _DIRECTORY_INDEX is None or _DIRECTORY_INDEX[0] is not files_db: + index: dict[str, list[tuple[str, dict]]] = {} + for sha1, entry in files_db.items(): + directory = entry.get("path", "").rsplit("/", 1)[0] + "/" + index.setdefault(directory, []).append((sha1, entry)) + _DIRECTORY_INDEX = (files_db, index) + return _DIRECTORY_INDEX[1] + + def _archive_prefix_extras( profiles: dict, relevant: set, diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index 07a58a0d..6bcec033 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -3698,5 +3698,24 @@ class AZipMemberIsHashedOnce(unittest.TestCase): self.assertEqual(len(opened), 1) + +class CompanionsComeFromADirectoryIndex(unittest.TestCase): + """_companions walked the whole database per scanned image.""" + + def test_same_answer_one_walk(self): + from scripts import packextras + + files_db = { + "a": {"path": "bios/Sony/PS2/ps2.bin", "name": "ps2.bin"}, + "b": {"path": "bios/Sony/PS2/ps2.bin.rom1", "name": "ps2.bin.rom1"}, + "c": {"path": "bios/Sony/PS2/ps2.nvm", "name": "ps2.nvm"}, + "d": {"path": "bios/Other/ps2.nvm", "name": "ps2.nvm"}, + } + found = packextras._companions("bios/Sony/PS2/ps2.bin", "ps2.bin", {"rom1", "nvm"}, files_db) + self.assertEqual([sha1 for sha1, _ in found], ["b", "c"]) + index = packextras._files_by_directory(files_db) + self.assertIs(packextras._files_by_directory(files_db), index) + + if __name__ == "__main__": unittest.main()