mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-09 03:23:47 -06:00
fix: index archives and sizes once in the check
A missing file walked every archive of the BIOS folder and every file of its size: 3,000 ZIPs and 3,000 missing files took 186 s, now under 1 s. --from copies and the owner of a refused file use the same lookups.
This commit is contained in:
1 parent
bfd82cedf8
commit
c6926e10b8
5 files changed
+275
-41
No files matched your search
@@ -17,6 +17,7 @@ import io
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
@@ -480,6 +481,44 @@ class MisplacedInTheBiosFolder(Scratch):
|
||||
self.assertNotIn("copied from", proc.stdout)
|
||||
|
||||
|
||||
class ManySameSizedFiles(FromFolder):
|
||||
"""A card of 16 KB ROMs and a list of 16 KB entries: each entry sorted
|
||||
and walked every file of its size."""
|
||||
|
||||
def test_each_file_is_read_once_and_the_order_holds(self):
|
||||
for n in range(3000):
|
||||
self.keep(f"roms/r{n:04}.bin", b"%016d" % n)
|
||||
_zip(self.old / f"sets/s{n:04}.zip", {f"m{n}.bin": b"m%015d" % n})
|
||||
entries = [{"dest": f"e{n}.bin", "size": 16, "sha1": f"{n:040}"}
|
||||
for n in range(3000)]
|
||||
wanted = [_entry("late.bin", b"%016d" % 2999, ["x"]),
|
||||
_entry("m5.bin", b"m%015d" % 5, ["x"]),
|
||||
_entry("r0007.bin", b"%016d" % 7, ["x"])]
|
||||
index = install.FolderIndex(self.old)
|
||||
start = time.monotonic()
|
||||
copies = install.plan_local_copies(entries + wanted, self.dest, None, [index])
|
||||
elapsed = time.monotonic() - start
|
||||
self.assertEqual({e["dest"]: copies[id(e)].where() for e in wanted if id(e) in copies}, {
|
||||
"late.bin": "roms/r2999.bin",
|
||||
"m5.bin": "sets/s0005.zip, inside as m5.bin",
|
||||
"r0007.bin": "roms/r0007.bin",
|
||||
})
|
||||
self.assertEqual(len(copies), 3)
|
||||
self.assertLess(elapsed, 30, f"{elapsed:.1f} s")
|
||||
|
||||
def test_a_file_of_the_same_name_comes_first(self):
|
||||
self.keep("a/other.bin", US)
|
||||
self.keep("b/scph5501.bin", US)
|
||||
_zip(self.old / "c.zip", {"x/gba.bin": GBA})
|
||||
_zip(self.old / "d.zip", {"gba_bios.bin": GBA})
|
||||
index = install.FolderIndex(self.old)
|
||||
files = json.loads(self.list.read_text())["files"]
|
||||
copies = install.plan_local_copies(files, self.dest, None, [index])
|
||||
found = {e["dest"]: copies[id(e)].where() for e in files if id(e) in copies}
|
||||
self.assertEqual(found["scph5501.bin"], "b/scph5501.bin")
|
||||
self.assertEqual(found["gba_bios.bin"], "d.zip, inside as gba_bios.bin")
|
||||
|
||||
|
||||
class TheSummaryLine(unittest.TestCase):
|
||||
def test_the_parts_in_words(self):
|
||||
line = install.sources_line([("E:\\", 38)], fixed=0, downloaded=4, missing=2)
|
||||
|
||||
@@ -19,6 +19,7 @@ import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import unittest
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
@@ -243,6 +244,58 @@ class CheckNamesWhyAFileIsRefused(Scratch):
|
||||
self.assertNotIn("opened at", proc.stdout)
|
||||
|
||||
|
||||
class ArchivesInTheBiosFolder(Scratch):
|
||||
"""The reason an archive gives is the first archive, in the order the
|
||||
folder is read, that holds the file or carries its name."""
|
||||
|
||||
def zipped(self, relative: str, members: dict[str, bytes]) -> None:
|
||||
path = self.dest / relative
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with zipfile.ZipFile(path, "w") as archive:
|
||||
for name, data in members.items():
|
||||
archive.writestr(name, data)
|
||||
|
||||
def test_each_reason_names_the_first_archive_that_answers(self):
|
||||
self.zipped("a.zip", {"x.bin": b"x"})
|
||||
self.zipped("x.zip", {"other": b"o"})
|
||||
self.zipped("b.zip", {"other": b"o"})
|
||||
self.zipped("c.zip", {"bios/b.bin": b"b"})
|
||||
self.place("y.7z", b"7z")
|
||||
self.zipped("sub/z.zip", {"Z.BIN": b"z"})
|
||||
self.zipped("elsewhere/w.zip", {"w.bin": b"w"})
|
||||
self.zipped("listed.zip", {"v.bin": b"v"})
|
||||
entries = {dest: _entry(dest, dest.encode() * 3, ["x"]) for dest in (
|
||||
"x.bin", "b.bin", "y.bin", "sub/z.bin", "w.bin", "v.bin")}
|
||||
files = [*entries.values(), _entry("listed.zip", b"zip", ["x"])]
|
||||
found = install.diagnose(list(entries.values()), [], files, self.dest)
|
||||
self.assertEqual({dest: found.reasons.get(id(e), "") for dest, e in entries.items()}, {
|
||||
"x.bin": "still zipped: it is inside a.zip",
|
||||
"b.bin": "still zipped: b.zip needs extracting",
|
||||
"y.bin": "still zipped: y.7z needs extracting",
|
||||
"sub/z.bin": "still zipped: it is inside sub/z.zip",
|
||||
"w.bin": "",
|
||||
"v.bin": "",
|
||||
})
|
||||
|
||||
def test_many_archives_and_many_missing_files_take_one_pass(self):
|
||||
"""1,519 ZIPs and 2,000 missing files took 57 seconds: each missing
|
||||
file walked every archive of the folder."""
|
||||
self.dest.mkdir()
|
||||
for n in range(3000):
|
||||
with zipfile.ZipFile(self.dest / f"set{n:04}.zip", "w") as archive:
|
||||
archive.writestr(f"rom{n}.bin", b"x")
|
||||
(self.dest / f"same{n:04}.bin").write_bytes(b"%016d" % n)
|
||||
missing = [{"dest": f"file{n}.bin", "size": 16 if n % 2 else 1000 + n,
|
||||
"sha1": f"{n:040}"} for n in range(3000)]
|
||||
missing.append(_entry("rom7.bin", b"r", ["x"]))
|
||||
start = time.monotonic()
|
||||
found = install.diagnose(missing, [], missing, self.dest)
|
||||
elapsed = time.monotonic() - start
|
||||
self.assertEqual(found.reasons, {
|
||||
id(missing[-1]): "still zipped: it is inside set0007.zip"})
|
||||
self.assertLess(elapsed, 30, f"{elapsed:.1f} s")
|
||||
|
||||
|
||||
def _pack(directory: Path, name: str, members: dict[str, bytes]) -> Path:
|
||||
"""A pack as generate_pack writes one: the files and a manifest.json."""
|
||||
listed = [{"path": path, "sha1": _sha1(data), "md5": hashlib.md5(data).hexdigest(),
|
||||
|
||||
Reference in new issue
Block a user