Point-in-Time Reads from a Timestamped Key-Value Store
Cockroach LabsSoftware Engineer · OnsiteLast updated
Build a versioned key-value store whose reads return the value a key held at a given timestamp: the latest write at or before that time, or an empty string if there is none. Tests choosing a per-key data layout that keeps point-in-time lookups fast across up to 200,000 operations.
Implement a key-value store that keeps every version of each key. A write records a value for a key at a timestamp without discarding earlier versions, and a read asks for a key as of a timestamp and returns the value that was current at that time.
The interviewer's focus is the data structure behind the read: a read should not have to scan through every version of its key.
So that the store can be called as one function, it is driven by a list of operations that are processed in order, and you return the results of the reads.
Function Signature
def run_versioned_store(operations: list[tuple]) -> list[str]:
Each operation is one of:
("set", key, value, timestamp): storevalueforkeyat timetimestamp.("get", key, timestamp): readkeyas of timetimestamp.
Rules
- A
getconsiders only thesetoperations for the samekeythat appear earlier in the list. Among those, it returns thevalueof the one with the largest timestamp that is less than or equal to theget's timestamp. - If there is no such
set, because the key has never been set or every earliersetof the key has a larger timestamp, thegetreturns the empty string"". - A
setnever removes earlier versions of its key. - Return one string per
get, in the order thegetoperations appear. Return an empty list if there are nogetoperations.
Constraints
1 <= len(operations) <= 2 * 10^5- Every
keyandvalueis a non-empty string of at most 100 lowercase English letters and digits. 1 <= timestamp <= 10^7in every operation.- The timestamps of the
setoperations strictly increase in the order those operations appear, across all keys. The timestamps ofgetoperations can be any value in range, in any order.
Examples
Example 1
Input: operations = [("set", "price", "10", 5), ("get", "price", 4), ("get", "price", 5),
("set", "price", "12", 9), ("get", "price", 8), ("get", "price", 9),
("get", "price", 100)]
Output: ["", "10", "10", "12", "12"]
At time 4 the key has no version yet. Reads at times 5 and 8 see the version written at time 5, because the version written at time 9 is later than 8. Reads at times 9 and 100 see the version written at time 9.
Example 2
Input: operations = [("set", "a", "x", 1), ("set", "b", "y", 2), ("get", "a", 2),
("get", "b", 1), ("set", "a", "z", 3), ("get", "a", 3), ("get", "c", 3)]
Output: ["x", "", "z", ""]
Key b was first written at time 2, so a read at time 1 finds nothing. Key c is never written.
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.