Fix the replay of a cache with expiry

Review the AI's codeEasy10 min

Your task

An agent's Go cache with a TTL (time to live: how long an entry stays valid) deleted expired keys while holding only a read lock. A delete is a write, so concurrent gets raced on the map. The team wants a replay of the corrected logic against a logical clock, so the rules can be tested without threads.

An assistant wrote replay_cache_ops(op_lines). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • op_lines: the operations, in order. Each one is "set|key|value|expires_at", "get|key|now" or "size".
  • Return one string for each get and each size, in order.

Rules the tests check:

  • Split each line on |. Keys and values can be empty.
  • A set has exactly 4 parts, and the first part is "set". It stores the value with its deadline expires_at, replacing any entry for that key. It outputs nothing.
  • A get has exactly 3 parts, and the first part is "get":
    • No entry for the key: output "MISS".
    • now is greater than the entry's deadline: the entry has expired. Remove it from the cache and output "MISS".
    • Otherwise output the stored value. At now equal to the deadline the entry is still live.
  • "size" is exactly that line. Output the number of entries stored right now, as a string such as "2". This includes expired entries that no get has removed yet.
  • expires_at and now must be 1 to 15 digits, 0 to 9. A set or get with any other time is skipped: no output and no change.
  • Every other line is skipped. Operation names are case sensitive.
  • Each get uses only its own now. Times do not have to increase from one line to the next.

Examples

replay_cache_ops(op_lines: list[str]) -> list[str]
Example 1
Inputreplay_cache_ops(["set|a|alpha|10", "get|a|5", "get|a|10", "get|a|11", "get|a|12", "size"])
Output["alpha", "alpha", "MISS", "MISS", "0"]
Example 2
Inputreplay_cache_ops(["set|a|1|5", "set|b|2|100", "get|a|6", "size", "get|b|7", "size"])
Output["MISS", "1", "2", "1"]