Convert Stack Samples into Trace Events
Company: Anthropic
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Onsite
# Convert Stack Samples into Trace Events
The source reports converting sampled call stacks into trace events but does not provide the exact tuple format or boundary rules. The interface and ordering below are deterministic practice assumptions.
A sampling profiler records snapshots of the active call stack. Each sample is `(timestamp, stack)`, where `stack` lists function names from root to currently executing leaf. Samples are sorted by strictly increasing timestamp.
Convert the samples into a minimal timeline of trace events:
```python
def samples_to_events(
samples: list[tuple[int, list[str]]],
end_time: int,
) -> list[tuple[int, str, str]]:
...
```
Each output event is `(timestamp, kind, function)`, where `kind` is `"start"` or `"end"`. At the first sample, start every frame in root-to-leaf order. Between consecutive samples, retain their longest common prefix, end frames that disappeared in leaf-to-root order, and start new frames in root-to-leaf order. At `end_time`, close every remaining frame leaf first.
## Constraints and Clarifications
- Timestamps and `end_time` are nonnegative integers. For a nonempty sample list, `end_time` is not earlier than the final sample.
- If `samples` is empty, return `[]` for every nonnegative `end_time`; there is no active stack to start or close.
- Empty stacks are allowed.
- Repeated function names at different depths represent distinct active frames.
- Events sharing a timestamp must follow the end-before-start ordering above.
- The result reflects stack changes visible in samples; it cannot infer calls entirely between samples.
## Hints
- Compare adjacent stacks only until their first differing depth.
- Make ordering at a shared timestamp explicit in tests.
- The total work should be proportional to the input stack sizes plus emitted events.
Quick Answer: Convert sampled root-to-leaf call stacks into a minimal sequence of start and end trace events. Use longest common prefixes between samples, close frames leaf-first, open frames root-first, and correctly handle shared timestamps and empty stacks.
Convert timestamped root-to-leaf stack samples into the minimal ordered start/end event timeline. Retain the longest common prefix between adjacent samples, end removed frames leaf-first, start added frames root-first, and close the final stack at end_time.
Constraints
- Sample timestamps are strictly increasing nonnegative integers.
- end_time is not earlier than the final sample.
- Empty stacks and repeated names at different depths are allowed.
- An empty sample list returns an empty event list.
Examples
Input: {'samples': [], 'end_time': 10}
Expected Output: []
Explanation: No samples imply no observed active frames.
Input: {'samples': [(2, ['main'])], 'end_time': 8}
Expected Output: [(2, 'start', 'main'), (8, 'end', 'main')]
Explanation: A single frame starts and then closes.
Hints
- Compare each sample with the active stack only until their first differing depth.
- Emit ends before starts at the same transition timestamp.