ITCHCPP 1.6.0
High-Performance NASDAQ TotalView-ITCH 5.0 Parser & Market-Data Platform
Loading...
Searching...
No Matches
order_index.hpp
Go to the documentation of this file.
1#pragma once
2
13
14#include <cstddef>
15#include <cstdint>
16#include <vector>
17
18namespace itch::book {
19
30 public:
32 static constexpr std::uint32_t NPOS = 0xFFFFFFFFU;
33
36 OrderIndex() { rehash(INITIAL_CAPACITY); }
37
40 [[nodiscard]] auto size() const noexcept -> std::size_t { return m_count; }
41
44 [[nodiscard]] auto empty() const noexcept -> bool { return m_count == 0; }
45
49 [[nodiscard]] auto find(std::uint64_t key) const noexcept -> std::uint32_t {
50 std::size_t slot = hash(key) & m_mask;
51 while (m_slots[slot].used) {
52 if (m_slots[slot].key == key) {
53 return m_slots[slot].value;
54 }
55 slot = (slot + 1) & m_mask;
56 }
57 return NPOS;
58 }
59
63 [[nodiscard]] auto contains(std::uint64_t key) const noexcept -> bool {
64 return find(key) != NPOS;
65 }
66
70 auto insert(std::uint64_t key, std::uint32_t value) -> void {
71 if ((m_count + 1) * LOAD_FACTOR_DEN >= m_slots.size() * LOAD_FACTOR_NUM) {
72 rehash(m_slots.size() * 2);
73 }
74 std::size_t slot = hash(key) & m_mask;
75 while (m_slots[slot].used) {
76 if (m_slots[slot].key == key) {
77 m_slots[slot].value = value;
78 return;
79 }
80 slot = (slot + 1) & m_mask;
81 }
82 m_slots[slot] = Slot {key, value, true};
83 ++m_count;
84 }
85
88 auto erase(std::uint64_t key) -> void {
89 std::size_t slot = hash(key) & m_mask;
90 while (m_slots[slot].used) {
91 if (m_slots[slot].key == key) {
92 remove_at(slot);
93 return;
94 }
95 slot = (slot + 1) & m_mask;
96 }
97 }
98
100 auto clear() -> void {
101 for (auto& slot : m_slots) {
102 slot.used = false;
103 }
104 m_count = 0;
105 }
106
107 private:
108 struct Slot {
109 std::uint64_t key {0};
110 std::uint32_t value {0};
111 bool used {false};
112 };
113
114 static constexpr std::size_t INITIAL_CAPACITY = 1024;
115 static constexpr std::size_t LOAD_FACTOR_NUM = 7; // Grow past 70% load.
116 static constexpr std::size_t LOAD_FACTOR_DEN = 10;
117
123 [[nodiscard]] static auto hash(std::uint64_t key) noexcept -> std::size_t {
124 key ^= key >> 33;
125 key *= 0xFF51AFD7ED558CCDULL;
126 key ^= key >> 33;
127 key *= 0xC4CEB9FE1A85EC53ULL;
128 key ^= key >> 33;
129 return static_cast<std::size_t>(key);
130 }
131
136 auto remove_at(std::size_t hole) -> void {
137 m_slots[hole].used = false;
138 --m_count;
139 std::size_t next = (hole + 1) & m_mask;
140 while (m_slots[next].used) {
141 const std::size_t home = hash(m_slots[next].key) & m_mask;
142 // Move the entry into the hole if its home position is not within the
143 // cyclic interval (hole, next], i.e. the hole sits between its home
144 // and its current slot.
145 const bool movable =
146 (hole <= next) ? (home <= hole || home > next) : (home <= hole && home > next);
147 if (movable) {
148 m_slots[hole] = m_slots[next];
149 m_slots[next].used = false;
150 hole = next;
151 }
152 next = (next + 1) & m_mask;
153 }
154 }
155
159 auto rehash(std::size_t new_capacity) -> void {
160 std::vector<Slot> old = std::move(m_slots);
161 m_slots.assign(new_capacity, Slot {});
162 m_mask = new_capacity - 1;
163 m_count = 0;
164 for (const auto& slot : old) {
165 if (slot.used) {
166 insert(slot.key, slot.value);
167 }
168 }
169 }
170
171 std::vector<Slot> m_slots;
172 std::size_t m_count {0};
173 std::size_t m_mask {0};
174};
175
176} // namespace itch::book
A flat, open-addressed hash map from order reference number to pool index, used for O(1) order lookup...
auto clear() -> void
Drops all keys (retaining capacity).
static constexpr std::uint32_t NPOS
Sentinel returned by find when a key is absent.
OrderIndex()
Constructs an empty map with the initial table capacity pre-allocated.
auto size() const noexcept -> std::size_t
The number of stored keys.
auto find(std::uint64_t key) const noexcept -> std::uint32_t
Returns the value for key, or NPOS if absent.
auto contains(std::uint64_t key) const noexcept -> bool
Whether key is present.
auto insert(std::uint64_t key, std::uint32_t value) -> void
Inserts or overwrites the value for key.
auto empty() const noexcept -> bool
Whether the map holds no keys.
auto erase(std::uint64_t key) -> void
Removes key if present, repairing the probe chain in place.