Problem: Design In-Memory Trade Subscription Processor
You are tasked with designing and implementing the internal logic for an in-memory trade subscription processor in C++. The system needs to efficiently handle incoming market trades and notify registered subscribers based on their filtering criteria.
Provided Interface
A simplified C++ interface for the TreadProcessor class is provided:
using HANDLE = int;
struct Tread {
std::string symbol; // e.g. "AAPL"
int size; // number of shares
std::string flag; // e.g. trade condition / venue flag
};
class TreadProcessor {
public:
TreadProcessor() {}
// Called whenever a new trade arrives from the market feed.
void onNewTread(const Tread &tread);
// Register interest in trades matching a given template.
// Returns a handle that can later be used to unsubscribe.
HANDLE subscribe(const Tread &filter,
std::function<void(const Tread &)> callback);
// Cancel a previous subscription.
void unSubscribe(HANDLE handle);
private:
// Design and add your internal data structures here.
};
Assumptions and Matching Logic
- A subscription is defined by a
filterof typeTreadand acallbackfunction. - A new trade
tdelivered viaonNewTreadmatches a subscriptionfilterif:t.symbol == filter.symbol(exact match), AND- Optionally, for this question, you can assume
sizeandflagmust also match if they are non-zero / non-empty in the filter. This means the filter can act as a simple template with optional fields.
- If a trade matches multiple subscriptions, all corresponding callbacks must be invoked with the trade.
Functional Requirements
subscribe(filter, callback):- Registers a new subscription using the given
filterandcallback. - Returns a unique
HANDLEthat identifies this subscription.
- Registers a new subscription using the given
onNewTread(tread):- Called for every incoming trade.
- Must efficiently find all subscriptions that match
treadand invoke their callbacks.
unSubscribe(handle):- Cancels the subscription associated with
handleso that its callback is no longer invoked for future trades.
- Cancels the subscription associated with
Non-functional Requirements and Design Goals
- There can be up to
10^5active subscriptions. - There can be tens of thousands of trades per second.
- Aim for efficient average time complexity for
onNewTreadandsubscribe. - Design for reasonable memory usage.
- Assume at least one thread will be calling
onNewTread, and another thread may be adding/removing subscriptions. Discuss how you would handle thread safety.
Task
Describe and justify a design for the internals of TreadProcessor. Your solution should cover:
- The internal data structures you will store in the
privatesection to support fast matching. - How
subscribe,onNewTread, andunSubscribewill be implemented conceptually using these data structures. - An analysis of the time and space complexity of your design.
- A discussion on how you would handle concurrency (e.g., locks, lock-free approaches, sharding, or other strategies) to support high throughput while maintaining correctness.
AI interview prep
Core dilemma
Balancing extremely high-throughput trade processing with efficient multi-field subscription matching (including optional fields) and robust thread safety, all within strict latency and memory constraints.
3 tradeoffs and 3 stress tests locked
Interview prep
Unlock the interviewer X-Ray rubric, tradeoff matrix, stress tests, clarifying questions, and key concepts.
Problem: Design In-Memory Trade Subscription Processor
You are tasked with designing and implementing the internal logic for an in-memory trade subscription processor in C++. The system needs to efficiently handle incoming market trades and notify registered subscribers based on their filtering criteria.
Provided Interface
A simplified C++ interface for the TreadProcessor class is provided:
using HANDLE = int;
struct Tread {
std::string symbol; // e.g. "AAPL"
int size; // number of shares
std::string flag; // e.g. trade condition / venue flag
};
class TreadProcessor {
public:
TreadProcessor() {}
// Called whenever a new trade arrives from the market feed.
void onNewTread(const Tread &tread);
// Register interest in trades matching a given template.
// Returns a handle that can later be used to unsubscribe.
HANDLE subscribe(const Tread &filter,
std::function<void(const Tread &)> callback);
// Cancel a previous subscription.
void unSubscribe(HANDLE handle);
private:
// Design and add your internal data structures here.
};
Assumptions and Matching Logic
- A subscription is defined by a
filterof typeTreadand acallbackfunction. - A new trade
tdelivered viaonNewTreadmatches a subscriptionfilterif:t.symbol == filter.symbol(exact match), AND- Optionally, for this question, you can assume
sizeandflagmust also match if they are non-zero / non-empty in the filter. This means the filter can act as a simple template with optional fields.
- If a trade matches multiple subscriptions, all corresponding callbacks must be invoked with the trade.
Functional Requirements
subscribe(filter, callback):- Registers a new subscription using the given
filterandcallback. - Returns a unique
HANDLEthat identifies this subscription.
- Registers a new subscription using the given
onNewTread(tread):- Called for every incoming trade.
- Must efficiently find all subscriptions that match
treadand invoke their callbacks.
unSubscribe(handle):- Cancels the subscription associated with
handleso that its callback is no longer invoked for future trades.
- Cancels the subscription associated with
Non-functional Requirements and Design Goals
- There can be up to
10^5active subscriptions. - There can be tens of thousands of trades per second.
- Aim for efficient average time complexity for
onNewTreadandsubscribe. - Design for reasonable memory usage.
- Assume at least one thread will be calling
onNewTread, and another thread may be adding/removing subscriptions. Discuss how you would handle thread safety.
Task
Describe and justify a design for the internals of TreadProcessor. Your solution should cover:
- The internal data structures you will store in the
privatesection to support fast matching. - How
subscribe,onNewTread, andunSubscribewill be implemented conceptually using these data structures. - An analysis of the time and space complexity of your design.
- A discussion on how you would handle concurrency (e.g., locks, lock-free approaches, sharding, or other strategies) to support high throughput while maintaining correctness.