Implement a hierarchical key-value store
Company: DoorDash
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Technical Screen
Quick Answer: Implement a hierarchical key-value store evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Constraints
- Paths are non-empty strings beginning with '/'.
- The root '/' always exists with initial value '#' and cannot be deleted.
- Create fails if the immediate parent does not exist or if the node already exists.
- Set/Get require the target node to already exist.
- Delete requires the node to exist and to have no children.
- Values are arbitrary strings.
Examples
Input: ([['get', '/']],)
Expected Output: ['#']
Explanation: The root node is pre-populated with value '#'.
Input: ([['create', '/a', 'x'], ['get', '/a'], ['set', '/a', 'y'], ['get', '/a']],)
Expected Output: [True, 'x', True, 'y']
Explanation: Create under existing root succeeds; Set overwrites the value, confirmed by the second Get.
Input: ([['create', '/a/b', 'oops']],)
Expected Output: [False]
Explanation: Create fails because the parent '/a' does not exist.
Input: ([['create', '/a', 'x'], ['create', '/a', 'z'], ['create', '/a/b', 'child'], ['get', '/a/b']],)
Expected Output: [True, False, True, 'child']
Explanation: Duplicate Create on '/a' is rejected; creating the child '/a/b' under the now-existing parent succeeds.
Input: ([['create', '/a', 'x'], ['create', '/a/b', 'c'], ['delete', '/a'], ['delete', '/a/b'], ['delete', '/a'], ['get', '/a']],)
Expected Output: [True, True, False, True, True, None]
Explanation: Delete on '/a' fails while it has the child '/a/b'; after the leaf '/a/b' is deleted, '/a' becomes a leaf and can be deleted; the final Get returns None.
Input: ([['get', '/missing'], ['set', '/missing', 'v'], ['delete', '/missing'], ['delete', '/']],)
Expected Output: [None, False, False, False]
Explanation: Operations on a non-existent node fail (Get returns None; Set/Delete return False); the root cannot be deleted.
Input: ([],)
Expected Output: []
Explanation: Empty operation list yields an empty result list.
Hints
- Store every node under its full path (e.g. '/a/b') in a flat hash map keyed by path, instead of nesting dicts — this makes existence checks O(1).
- Keep a separate children map (path -> set of child full-paths) so Delete can reject non-leaf nodes in O(1) and Create can validate the parent quickly.
- Derive a node's parent by trimming after the last '/'; the parent of '/a' is '/', and the parent of '/a/b' is '/a'. Handle the root '/' as a special case.
- For concurrency, guard the maps with a read-write lock (or per-subtree locks); for persistence, append each mutating op to a write-ahead log and replay it on startup.