A cache uses this persistence strategy: before an operation is considered successful, it writes a durable journal record. A cache miss writes ('PUT', func_name, args, kwargs, value), which means the computed value for that key is now stored and becomes the most recently used entry. A cache hit writes ('HIT', func_name, args, kwargs), which means that existing key becomes the most recently used entry. Keys are deterministic and must be built as (func_name, tuple(args), tuple(sorted(kwargs.items()))), so different keyword argument orders represent the same key. After a crash, only the journal prefix given in the input survived. Reconstruct the exact recovered cache state by replaying the journal in order with LRU eviction. If a 'HIT' references a key that is not currently present during replay, ignore it. Return the recovered cache contents from most-recently-used to least-recently-used as a list of (canonical_key, value).
Examples
Input: (2, [('PUT', 'add', [1, 2], {}, 3), ('PUT', 'mul', [2, 3], {}, 6), ('HIT', 'add', [1, 2], {})])
Expected Output: [(('add', (1, 2), ()), 3), (('mul', (2, 3), ()), 6)]
Explanation: The hit on 'add' makes it the most recently used entry.
Input: (2, [('PUT', 'add', [1, 2], {}, 3), ('PUT', 'mul', [2, 3], {}, 6), ('PUT', 'pow', [2, 5], {}, 32), ('HIT', 'add', [1, 2], {})])
Expected Output: [(('pow', (2, 5), ()), 32), (('mul', (2, 3), ()), 6)]
Explanation: When 'pow' is inserted, 'add' is evicted as the least recently used entry. The later hit on 'add' is ignored because that key is no longer present.
Input: (2, [('PUT', 'affine', [5], {'scale': 2, 'bias': 1}, 11), ('PUT', 'add', [1, 1], {}, 2), ('HIT', 'affine', [5], {'bias': 1, 'scale': 2})])
Expected Output: [(('affine', (5,), (('bias', 1), ('scale', 2))), 11), (('add', (1, 1), ()), 2)]
Explanation: Keyword argument order is normalized during recovery, so the hit matches the existing 'affine' entry.
Input: (0, [('PUT', 'add', [1, 2], {}, 3), ('HIT', 'add', [1, 2], {})])
Expected Output: []
Explanation: Edge case: capacity 0 means the recovered cache is empty.
Input: (3, [])
Expected Output: []
Explanation: Edge case: an empty durable journal recovers an empty cache.