Quick Overview

Implement a transactional in-memory parcel store with event totals, modification-based ranking, courier assignments, release, undo, and sign-out. Follow the exact blocking, snapshot, deletion, ownership, return-value, and counter rules across up to 100,000 operations.

Implement a Transactional Parcel-Tracking Store

Company: Klaviyo

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: hard

Interview Round: Online Assessment

## Problem Implement an in-memory parcel-tracking store. It maintains per-parcel event totals, ranks parcels by successful event-data modifications, supports courier assignments, and can undo changes made during one assignment. Implement `runParcelStore(operations)`. Process operations in order and return one encoded result row per operation. ### Portable Input and Result Encoding `operations` is an array of string arrays. Every field, including a numeric field, is passed as a string. A numeric field uses canonical base-10 signed-integer text: `0`, a nonzero digit followed by digits, or `-` followed by a nonzero digit and digits. A leading `+`, leading zero, whitespace, and `-0` are not used. All supplied rows have one of the exact valid shapes below. Return an array of string arrays with the same length as `operations`: - Encode an integer result as a one-element row containing its canonical decimal text, for example `["5"]`. - Encode a Boolean result as `["true"]` or `["false"]`. - Encode a string result as a one-element row, for example `["acquired"]`. - Encode `null` as `["null"]`. - For `top`, use the ranked strings themselves as the result row. An empty ranking is `[]`. This uniform `string[][]` result is the public return value; implementations must not return language-specific unions, objects, null values, or mixed scalar/list elements. ### Operation Contract - `["record", parcelId, eventType, countText]`: parse `countText` and add it to the event total. A missing parcel and event may be created. Return the new total. If the parcel is assigned, block the call and return the current total for that event, or `null` if absent. - `["get", parcelId, eventType]`: return the total, or `null` if the parcel or event is absent. - `["remove", parcelId, eventType]`: remove the event and return whether it existed. Block the call with `false` while the parcel is assigned. Delete unassigned parcel data when its last event is removed. - `["top", nText]`: parse `nText`, sort existing parcel data by modification count descending and then parcel ID ascending under ordinal ASCII order, and return up to `n` strings formatted `parcelId>(count)`. Return an empty row for `n <= 0` or no parcels. - `["assign", courierId, parcelId]`: return `"acquired"` on success, `"already_locked"` if another courier holds it, `null` if the same courier already holds it, or `"invalid_request"` if no parcel data exists. - `["release", parcelId]`: release an assignment and return `"released"`; return `null` when parcel data exists but is unassigned; return `"invalid_request"` when neither data nor assignment exists. An assignment survives deletion of all event data by its authorized courier. - `["courier_record", parcelId, eventType, countText, courierId]` and `["courier_remove", parcelId, eventType, courierId]`: behave like the regular operation when unassigned or held by that courier. When another courier holds the parcel, return the unchanged event total or `null` for record, and `false` for remove. - `["undo", courierId, parcelId]`: if that courier currently holds the parcel, restore event data and modification count to the exact assignment-time snapshot, release it, and return `true`; otherwise return `false`. - `["sign_out", courierId]`: release all assignments held by that courier without undoing data and return the number released. ### Modification-Count Rules - Creating parcel data initializes its counter to `0`. - Each later successful record or removal changes the counter by one. - Blocked, missing, get, top, assign, release, undo, and sign-out operations do not increment it. - Removing the last event deletes the parcel's current data and ranking counter. Undo may restore both from a snapshot. ### Constraints & Assumptions - `1 <= len(operations) <= 100,000`. - Parcel IDs are nonempty ASCII strings. Compare parcel IDs lexicographically by unsigned ASCII character value, with a shorter prefix ordered before a longer string; do not use locale, case folding, or Unicode normalization. - Courier IDs and event types are nonempty strings. - Every count, event total, `n`, modification counter, and released-assignment count fits in a signed 64-bit integer. - Counts may be negative; storing a zero total does not remove an event. - Assignment snapshots must not alias mutable live maps. ### Clarifying Questions to Ask - Does an assignment survive deletion of the parcel's last event? Yes, until release, undo, or sign-out. - Does sign-out revert event changes? No. - What state does undo restore? Both event data and the ranking counter from assignment time. - Can an unassigned parcel be changed through courier methods? Yes, by any courier ID. ```hint Separate current data from lock state An assignment can outlive all current event data, so do not store ownership only inside the parcel-data object. ``` ```hint Snapshot on assignment Undo should replace current state with a deep copy captured when the courier acquired the parcel; replaying inverse operations is more error-prone. ``` ### Example ```text operations = [ ["record", "P1", "scan", "2"], ["record", "P1", "scan", "3"], ["assign", "C1", "P1"], ["courier_remove", "P1", "scan", "C1"], ["get", "P1", "scan"], ["undo", "C1", "P1"], ["get", "P1", "scan"], ["top", "1"] ] output = [ ["2"], ["5"], ["acquired"], ["true"], ["null"], ["true"], ["5"], ["P1>(1)"] ] ``` ### Evaluation Focus - Parses numeric tokens identically and emits only the specified string-row encoding. - Preserves all blocking and return-value distinctions. - Keeps assignments valid when event data disappears. - Restores an independent snapshot and counter on undo. - Deletes and restarts ranking state correctly, using ordinal ASCII parcel-ID order for ranking ties. - Reuses core mutation logic for regular and courier-authorized calls. ### Extensions to Discuss 1. How would a heap or ordered index make frequent `top` queries faster? 2. What synchronization would be required for concurrent operations? 3. How would snapshots change if parcel event maps were very large?

Overview: Implement a transactional in-memory parcel store with event totals, modification-based ranking, courier assignments, release, undo, and sign-out. Follow the exact blocking, snapshot, deletion, ownership, return-value, and counter rules across up to 100,000 operations.

Process exact-shape string-array operations for an in-memory parcel event store, returning one string-array result row per operation. Support record, get, remove, modification-count ranking, courier assignment and release, authorized courier mutations, assignment-time undo, and courier sign-out. Numeric fields are canonical signed-integer text and results uniformly encode integers, booleans, strings, null, and top rankings as string rows. Parcel ranking uses modification count descending then unsigned ordinal-ASCII parcel ID ascending. Assignment ownership and its independent snapshot can survive deletion of all live parcel data.

Constraints

  • 1 <= len(operations) <= 100,000 and every row has one stated exact shape.
  • Parcel IDs are nonempty ASCII strings ordered by unsigned ordinal ASCII.
  • Courier IDs and event types are nonempty strings.
  • All numeric fields and results fit signed 64-bit integers.
  • Counts may be negative, and a stored zero total remains present.

Examples

Input: ([["record","P1","scan","2"],["record","P1","scan","3"],["assign","C1","P1"],["courier_remove","P1","scan","C1"],["get","P1","scan"],["undo","C1","P1"],["get","P1","scan"],["top","1"]],)

Expected Output: [['2'], ['5'], ['acquired'], ['true'], ['null'], ['true'], ['5'], ['P1>(1)']]

Explanation: Source example restores both data and count.

Input: ([["record","P","x","1"],["record","P","y","2"],["record","P","x","-1"],["top","1"],["remove","P","y"],["top","1"],["remove","P","x"],["top","1"],["record","P","z","5"],["top","1"]],)

Expected Output: [['1'], ['2'], ['0'], ['P>(2)'], ['true'], ['P>(3)'], ['true'], [], ['5'], ['P>(0)']]

Explanation: Creation, modification, deletion, and recreation follow counter rules.

Hints

  1. Store assignment ownership and its snapshot separately from current parcel data.
  2. Deep-copy both events and modification count when an assignment is acquired.

Loading coding console...

Show the approach

Approach

Keep current parcel data separate from assignment state. Each parcel stores an event-total map and modification counter; creation starts at zero, every later successful record or removal increments it, and last-event removal deletes current data. Assignment captures a deep parcel snapshot in an independent lock map. Central mutation helpers enforce regular and courier authorization uniformly, including blocked return values. Undo replaces current data from a fresh copy of the snapshot and releases the lock; sign-out only releases. Top sorts existing data by modification count and then the specified ASCII ID order. Parse numeric text into exact signed 64-bit values and emit only string rows.

Time complexity:
O(total operations + sum of O(p log p) for top queries)
Space complexity:
O(total live event data + assignments and snapshots)