Read Current and Historical Field Values with Expiration
Company: Meta
Role: Machine Learning Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Online Assessment
Implement `replayDatabase(operations)` for an initially empty in-memory database. Each value belongs to a `(key, field)` pair. Process operations in order and return the results of all `get` and `get_when` operations in that order.
### Inputs and Output
`operations` is a list of lists of strings. Each operation has one of these forms:
- `["set", time, key, field, value]`: assign a value without an expiration time.
- `["set_ttl", time, key, field, value, ttl]`: assign a value that is present from `time` through, but not including, `time + ttl`.
- `["delete", time, key, field]`: remove the value currently present at that pair, if any. This operation produces no output.
- `["get", time, key, field]`: return the value present at `time`.
- `["get_when", time, key, field, at]`: return the value that was present at the historical time `at`. This reads that pair's history without changing the current database.
Times and TTL durations are encoded as decimal strings. Return a list of strings. A read of an absent value returns `""`; stored values are nonempty.
### Rules and Constraints
- This practice version uses strictly increasing, nonnegative operation times. For `get_when`, `0 <= at <= time`; zero is an ordinary historical time.
- A write replaces the previous value at its operation time. A deletion ends the current value at its operation time. Expiration, replacement, or deletion does not erase the value's earlier history.
- An expired value does not become present again after a later value expires or is deleted. A subsequent ordinary `set` has no expiration, even if an earlier value had a TTL.
- Reads do not modify values, lifetimes, or operation times. A missing key or field has no value.
- There are at most 100,000 operations. Operation times and historical times are at most 1,000,000,000; TTL durations are integers from 1 through 1,000,000,000.
- Keys, fields, and values are case-sensitive ASCII strings of length 1 through 50. All operations are well formed. An empty operation list returns an empty list.
### Example 1
```text
operations = [
["set_ttl", "2", "account", "status", "trial", "3"],
["get", "4", "account", "status"],
["get", "5", "account", "status"],
["get_when", "6", "account", "status", "4"],
["get_when", "7", "account", "status", "5"]
]
Output: ["trial", "", "trial", ""]
```
The value is present on `[2, 5)`. A later historical read still sees it at time 4, but not at time 5.
### Example 2
```text
operations = [
["set", "1", "item", "state", "old"],
["set_ttl", "3", "item", "state", "new", "2"],
["delete", "4", "item", "state"],
["set", "6", "item", "owner", "team"],
["get_when", "7", "item", "state", "2"],
["get_when", "8", "item", "state", "3"],
["get_when", "9", "item", "state", "4"],
["get", "10", "item", "state"],
["get", "11", "item", "owner"]
]
Output: ["old", "new", "", "", "team"]
```
Deletion preserves both earlier versions. The old value does not return, and another field under the same key remains independent.
Overview: Process key-and-field database writes, TTL expiration, deletion, and historical reads while preserving past values without rolling back current state.