Asked at Citadel Securities, Jump Trading
Theory: Data Structures You Implement, Not ImportRead the problem, hints and solution here. The editor needs a bigger screen: open this page on a laptop to write and run your code.
Available in C++ and Python. You are solving it in C++. Switch to Python
Implement RingBuffer, a fixed-capacity first-in first-out queue over a pre-allocated buffer. push adds at the tail and fails when full. pop takes from the head.
Ring buffers sit in the hot path of low-latency systems: market-data handlers stage packets in them, loggers hand records across threads through them, and gateways queue outbound orders in them. They use a fixed block of memory, no allocation after construction, and index arithmetic instead of pointer chasing.
The interface is:
capacity (at least 1) and allocates storage for
exactly that many elements, once, there.push(value): appends at the tail; returns false (and changes nothing)
when full.pop(): removes and returns the head, or nothing when empty.front(): the head without removing it, or nothing when empty.size(), empty() and full().template <typename T>
class RingBuffer {
public:
explicit RingBuffer(std::size_t capacity);
bool push(const T& value);
std::optional<T> pop();
std::optional<T> front() const;
std::size_t size() const;
bool empty() const;
bool full() const;
};
pop() and front() return std::nullopt when empty. No std::deque,
std::queue, or std::list: the point is the index arithmetic over
contiguous storage (a std::vector<T> sized once in the constructor is fine as
the backing store). Indices must wrap; the buffer must keep working through
many times capacity operations.
RingBuffer<int> rb(2);
rb.push(1); // true
rb.push(2); // true
rb.push(3); // false (rejected: full)
RingBuffer<int> other(2);
other.push(7);
other.push(8);
*other.pop(); // 7
other.push(9);
*other.pop(); // 8
*other.pop(); // 9 (wrap-around preserves FIFO order)
capacity up to \(10^6\).capacity operations through a buffer, so per-operation shifting or
reallocation will not finish in time.
The largest hidden test runs 2,000,000 operations at capacity 1,000,000.full() and empty() must be exact (the classic head==tail ambiguity is
yours to resolve).More from Fixed storage