iq.lab
Python starts when a code cell comes near or you run one
mediumDesign as codingHash maps and setsStack target 25 min

Key-value store with transactions

Not solved yet

An interviewer hands you this store in three parts. Each part keeps every rule from the parts before it.

Part 1. Build a class KVStore:

  • KVStore() starts empty.
  • set(key, value) stores value under key, replacing any value already there.
  • get(key) returns the value stored under key, or None if there is none.
  • delete(key) removes key and its value. Deleting a key that holds nothing does nothing.

Part 2. Add transactions. A transaction is a group of changes that is kept or undone as a whole.

  • begin() opens a transaction.
  • rollback() undoes every set and delete made since that begin, then closes the transaction.
  • commit() closes the transaction and keeps its changes.
  • rollback() and commit() return True. When no transaction is open, they change nothing and return False.
  • get always returns the newest value, including changes made inside an open transaction.

Part 3. Transactions nest. A begin() while a transaction is open opens an inner one, and rollback() and commit() act on the innermost open transaction only. When an inner transaction commits, its changes join the transaction around it, so a later rollback() of the outer transaction undoes them too.

set, get, delete and begin must take O(1) time on average. rollback() and commit() may take time in proportion to the number of keys the closing transaction changed, but not to the size of the whole store.

Example 1
Inputset("a", 1), set("b", 2), get("a"), delete("a"), get("a"), get("b")Outputget("a") returns 1, then get("a") returns None, get("b") returns 2

Part 1 only: after the delete, a holds nothing.

Example 2
Inputset("x", 10), begin(), set("x", 20), set("y", 5), get("x"), rollback(), get("x"), get("y"), rollback()Outputget("x") returns 20, rollback() returns True, get("x") returns 10, get("y") returns None, rollback() returns False

Inside the transaction, get sees 20. The rollback puts x back to 10 and removes y, which did not exist before. The second rollback finds no open transaction.

Example 3
Inputset("x", 1), begin(), set("x", 2), begin(), set("x", 3), commit(), get("x"), rollback(), get("x")Outputcommit() returns True, get("x") returns 3, rollback() returns True, get("x") returns 1

The inner commit hands x = 3 to the outer transaction, so rolling the outer one back restores 1, the value from before the first begin.

Constraints
  • Keys and values are strings or integers. A value is never None.

  • Up to 106 calls in total.

  • The store can hold hundreds of thousands of keys while each transaction changes only a few.

Plan it first

Write a line for each before you code, then say them out loud. Compare with the Approach tab afterwards.

⌘+Enter runs 0:00Python starts when a code cell comes near or you run one
Run examples checks the examples. Submit runs every test, including edge cases and, when the problem has one, a speed check on a large input.