mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-16 16:33:27 -05:00
fix: key the opcode cache by content
This commit is contained in:
1 parent
d86215235e
commit
3a6f2c8770
2 files changed
+28
-5
No files matched your search
+11
-5
@@ -723,22 +723,28 @@ def _map_index(opcodes, index: int) -> int | None:
|
||||
return None
|
||||
|
||||
|
||||
_OPCODE_CACHE: dict[tuple[int, int], list] = {}
|
||||
_OPCODE_CACHE: dict[tuple[tuple[str, ...], tuple[str, ...]], list] = {}
|
||||
_OPCODE_CACHE_SIZE = 8
|
||||
|
||||
|
||||
def _opcodes(pin: list[str], head: list[str]) -> list:
|
||||
"""Opcodes for one pair of revisions, computed once per run.
|
||||
|
||||
Every ref citing the same file would otherwise redo the same diff, and a
|
||||
driver of thirty thousand lines takes seconds each time.
|
||||
driver of thirty thousand lines takes seconds each time. Keyed by the
|
||||
lines themselves: anchor_block hands over lists it builds and frees, and
|
||||
an id() key served one file's opcodes to the next pair at the same
|
||||
addresses.
|
||||
"""
|
||||
key = (id(pin), id(head))
|
||||
cached = _OPCODE_CACHE.get(key)
|
||||
key = (tuple(pin), tuple(head))
|
||||
cached = _OPCODE_CACHE.pop(key, None)
|
||||
if cached is None:
|
||||
cached = difflib.SequenceMatcher(
|
||||
None, pin, head, autojunk=False
|
||||
).get_opcodes()
|
||||
_OPCODE_CACHE[key] = cached
|
||||
_OPCODE_CACHE[key] = cached
|
||||
while len(_OPCODE_CACHE) > _OPCODE_CACHE_SIZE:
|
||||
del _OPCODE_CACHE[next(iter(_OPCODE_CACHE))]
|
||||
return cached
|
||||
|
||||
|
||||
|
||||
@@ -3397,6 +3397,23 @@ class TestWrappedProse(unittest.TestCase):
|
||||
self.assertEqual(self.path.read_text(), self.TEXT)
|
||||
|
||||
|
||||
class TestOpcodeCache(unittest.TestCase):
|
||||
"""The diff cache was keyed by id() of lists anchor_block builds and frees
|
||||
on return: a later pair at the same addresses read another file's
|
||||
opcodes, and a CHANGED ref could be mapped onto the wrong line."""
|
||||
|
||||
def test_each_pair_gets_its_own_diff(self):
|
||||
import difflib
|
||||
|
||||
for n in range(200):
|
||||
pin = [f"line {n} {i}" for i in range(n % 7 + 2)]
|
||||
head = [f"line {n} {i}" for i in range(n % 5 + 1)] + [f"new {n}"]
|
||||
expected = difflib.SequenceMatcher(
|
||||
None, pin, head, autojunk=False
|
||||
).get_opcodes()
|
||||
self.assertEqual(profile_sync._opcodes(list(pin), list(head)), expected)
|
||||
|
||||
|
||||
class TestCommentCitations(unittest.TestCase):
|
||||
"""The loader drops comments: zesarux's `# rom_load switch,
|
||||
src/cpu.c:3212-3451` stayed on the old lines under a new pin."""
|
||||
|
||||
Reference in new issue
Block a user