Execute TTL Cache Operations with Fetch-on-Miss
Company: Tubitv
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
# Execute TTL Cache Operations with Fetch-on-Miss
Implement a pure simulator for a TTL cache. The simulator includes put, get, delete, size, and a deterministic adapter for a loader-based fetch operation.
~~~python
def execute_ttl_cache(operations: list[list[object]]) -> list[list[object]]:
...
~~~
Operation formats are:
- ["put", time_ms, key, value, ttl_ms]
- ["get", time_ms, key]
- ["delete", time_ms, key]
- ["size", time_ms]
- ["fetch", time_ms, key, ttl_ms, loader_status, loader_payload]
Keys are strings and cached values are integers. Times are nonnegative integers in nondecreasing order. A positive TTL expires at put_time + ttl_ms, and the key is invalid at that exact time. TTL zero means no expiration.
The exact result for each operation is:
- put: ["ok"]
- get: ["ok", value] for a valid entry, otherwise ["ok", null]
- delete: ["ok", boolean], where the boolean is true when a stored key existed, even if it was expired
- size: ["ok", count], including stored expired entries
- fetch: return a valid cached value without consulting the supplied loader fields; on a miss or expired entry, loader_status is either "ok" or "error". For "ok", replace the entry with loader_payload and the supplied TTL, then return ["ok", value]. For "error", do not modify the cache and return ["error", reason].
Expired entries remain stored until delete or replacement. This makes the specified size behavior observable. The fetch operation represents the outcome of calling a loader rather than accepting a function object, so every input remains JSON-marshalable and deterministic.
## Constraints and Error Rules
- 0 <= len(operations) <= 200000
- ttl_ms is nonnegative.
- loader_payload is an integer when loader_status is "ok" and a string reason when it is "error".
- Malformed operations, decreasing timestamps, invalid types, or unknown names must raise ValueError.
- Return values are compared exactly.
## Example
~~~text
Input:
[
["put", 0, "u", 1, 5],
["get", 4, "u"],
["get", 5, "u"],
["size", 5],
["fetch", 6, "u", 10, "ok", 2],
["fetch", 7, "v", 0, "error", "db_down"],
["size", 7],
["delete", 8, "u"],
["size", 8]
]
Output:
[
["ok"],
["ok", 1],
["ok", null],
["ok", 1],
["ok", 2],
["error", "db_down"],
["ok", 1],
["ok", true],
["ok", 0]
]
~~~
## Hints
- Keep the stored record distinct from the result of checking whether it is currently valid.
- Fetch has a check phase and, only on a miss, a loader-outcome phase.
- Replacing an expired key should update all of its metadata.
Quick Answer: Implement a deterministic TTL cache simulator with put, get, delete, size, and fetch-on-miss operations. Preserve expired records until deletion or replacement, model loader success and failure explicitly, and validate timestamped JSON-compatible inputs.
Simulate put, get, delete, size, and deterministic loader-backed fetch operations for a TTL cache whose expired entries remain stored.
Constraints
- Timestamps are nonnegative and nondecreasing
- Positive TTL expires exactly at put time plus TTL
- TTL zero never expires
Examples
Input: []
Expected Output: []
Explanation: No operations produce no results.
Input: [['put', 0, 'a', 1, 5], ['get', 4, 'a']]
Expected Output: [['ok'], ['ok', 1]]
Explanation: A value is valid strictly before expiration.
Hints
- Store existence separately from current validity.
- Fetch consults loader fields only when the current record is missing or expired.