Fix the replay of a cache with expiry
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 deadlineexpires_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". nowis greater than the entry's deadline: the entry has expired. Remove it from the cache and output"MISS".- Otherwise output the stored value. At
nowequal to the deadline the entry is still live.
- No entry for the key: output
"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_atandnowmust 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
Input
replay_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
Input
replay_cache_ops(["set|a|1|5", "set|b|2|100", "get|a|6", "size", "get|b|7", "size"])Output
["MISS", "1", "2", "1"]