Implement store, evaluator, and parser
InstacartSoftware Engineer · OnsiteLast updated
This problem tests your ability to design a robust in-memory data store with versioning and TTL, implement an expression evaluator for dependencies, and parse a specialized stream of matrix data.
The Problem
You are tasked with building a core service for a real-time analytics engine. Implement a class AnalyticsStore that manages keys, their versioned values, and an expression evaluator for those values.
1. Key-Value Store with Versioning and TTL
Implement a store that supports:
put(key, value, ttl_ms): Stores a value with an associated time-to-live.get(key, version): Retrieves the value at a specific version. If no version is provided, return the latest. If the key has expired, returnnull.
2. Expression Evaluator
Keys can contain expressions in the format "val(key_a) + val(key_b)". When you retrieve a key, if the value is an expression, resolve its dependencies recursively. If a dependency is missing or expired, the expression evaluation fails.
3. Matrix Parser
Implement a function parse_stream(stream) that processes a string of newline-separated rows representing a matrix of values. Some cells may be expressions. The input format is "1,2,val(a);3,4,5". Convert this stream into a structured 2D array representation.
Interface
class AnalyticsStore:
def put(self, key: str, value: str, ttl_ms: int) -> None:
pass
def get(self, key: str, version: int = None) -> str:
# Resolves expressions if needed
pass
def parse_stream(self, stream: str) -> list[list[str]]:
# Processes matrix input
pass
Constraints
- The store must handle up to 10,000 keys.
- Circular dependencies in expressions must be detected and return an error.
- Versioning is non-negative and monotonically increasing for each key.
Examples
store = AnalyticsStore()
store.put("a", "10", 5000)
store.put("b", "20", 5000)
store.put("c", "val(a) + val(b)", 5000)
print(store.get("c")) # Output: "30"
Hints
Hint 1
Use a dictionary of lists to store key values, where each element is an object containing the timestamp, TTL, and the version index.
Hint 2
For expression evaluation, use a stack or recursion with a 'visited' set to detect circular dependencies during the DFS traversal.
Hint 3
For the matrix parser, split the input by newlines then by semicolons, ensuring you handle potential whitespace and empty cells.
Follow-up questions
- How would you modify the storage system to persist data to disk without sacrificing too much performance?
- If the expression language becomes complex (e.g., supporting multiplication or parentheses), how would you refactor the parser?
- How do you ensure thread-safety if multiple clients are putting and getting from the store simultaneously?
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.