Fix the TTL cache model for an upstream API
Your task
You asked an agent to cache an expensive API call in your Java service. Its first try cached forever, so data went stale. Its second added a time to live (TTL) but kept the cache inside the request, so nothing survived between calls. Instead of another one-line correction, your team wrote the cache's intent down as an executable check: replay a sequence of calls and count how many reach the upstream API.
An assistant wrote count_upstream_calls(keys, times, ttl_seconds). It is in the editor. It has a bug. Find it and fix it.
Input and output:
keys,times: two lists of the same length. Call i asks forkeys[i]at timetimes[i], in seconds. Calls are given in order.ttl_seconds: how long a cached entry stays fresh.- Return how many calls went upstream.
Rules the tests check:
- One cache is shared by every call in the process.
- If
ttl_secondsis 0 or less, caching is off and every call goes upstream. - Otherwise a call is a hit when its key has a cached entry and the call's time minus the entry's insertion time is less than
ttl_seconds. An entry exactlyttl_secondsold has expired. - A hit leaves the entry alone. Its age always counts from when it was inserted, not from when it was last read.
- Every other call goes upstream: count it, and store the key with the call's time as its insertion time.
- Keys are compared exactly, case included.
Examples
count_upstream_calls(keys: list[str], times: list[int], ttl_seconds: int) -> intExample 1
Input
count_upstream_calls(["a", "a"], [0, 1], 60)Output
1Example 2
Input
count_upstream_calls(["a", "a", "a"], [0, 100, 150], 60)Output
2Example 3
Input
count_upstream_calls(["a", "b", "a"], [0, 1, 2], 60)Output
2