Katkat

Implement Buffer Parsers and Generic Map Class

Hudson River TradingQuantitative Researcher · Online Assessment

Last updated

This problem tests your ability to safely parse binary data streams from raw memory buffers and implement a type-safe generic wrapper around standard associative containers.

Problem Description

In high-frequency trading systems, data is often received as a raw byte stream (a buffer). You are tasked with two objectives: creating a safe deserializer for binary structures and building a type-restricted map container.

Part 1: Binary Buffer Parsing

Implement a function parse_int32 that extracts a 4-byte signed integer from a raw uint8_t* buffer. You must handle the buffer pointer safely. If the request exceeds the buffer size, return an std::optional.

Part 2: Generic Map Wrapper

Implement a templated class TypedRegistry that wraps an std::unordered_map. The class must support:

  1. put(K key, V value): Inserts or updates the value.
  2. get(K key): Returns an std::optional if the key exists.
  3. remove(K key): Removes the entry if it exists.

Requirements

  • Ensure the parsing logic is robust against buffer overruns.
  • Use std::optional to communicate success or failure.
  • The TypedRegistry should be header-only and utilize standard containers.

Example

// Part 1
uint8_t buffer[] = {0x01, 0x00, 0x00, 0x00};
auto val = parse_int32(buffer, 4); // Returns 1

// Part 2
TypedRegistry registry;
registry.put(1, 3.14);
auto res = registry.get(1); // Returns 3.14

Constraints

  • Assume little-endian architecture.
  • Buffer size is provided explicitly.
  • Do not use C-style casts (e.g., (int*)ptr); use std::memcpy or bit-shifting to avoid alignment issues.

Hints

Hint 1

For the buffer parser, use bit-shifting or std::memcpy into a local variable to avoid undefined behavior caused by pointer aliasing or unaligned access.

Hint 2

For the TypedRegistry, keep the underlying std::unordered_map private to ensure encapsulation and use the find method to check for key existence before returning an optional.

Hint 3

When parsing the buffer, always validate the offset against the provided buffer length before attempting to read to prevent memory corruption.

Follow-up questions

  • How would you modify the parser to handle big-endian input regardless of the host system's endianness?
  • If this container were accessed by multiple threads simultaneously, what synchronization primitives would you introduce to ensure thread safety?
  • How could you modify the `TypedRegistry` to allow for custom hashing functions for complex user-defined types?