ITCHCPP 1.6.0
High-Performance NASDAQ TotalView-ITCH 5.0 Parser & Market-Data Platform
Loading...
Searching...
No Matches
sequencing.hpp
Go to the documentation of this file.
1#pragma once
2
12
13#include <algorithm>
14#include <cstdint>
15#include <functional>
16#include <optional>
17#include <string>
18#include <string_view>
19#include <unordered_map>
20
21namespace itch::transport {
22
31 public:
43 auto operator=(const RetransmitRequester&) -> RetransmitRequester& = default;
47 auto operator=(RetransmitRequester&&) noexcept -> RetransmitRequester& = default;
49 virtual ~RetransmitRequester() = default;
50
57 virtual auto request_retransmit(
58 std::string_view session, std::uint64_t start_sequence, std::uint64_t count
59 ) -> void = 0;
60};
61
72 public:
75 using GapCallback = std::function<
76 void(std::string_view session, std::uint64_t expected, std::uint64_t received)>;
77
86 auto observe(std::string_view session, std::uint64_t first_sequence, std::uint64_t count)
87 -> std::uint64_t {
88 const std::string key {session};
89 auto iter = m_expected_by_session.find(key);
90 if (iter == m_expected_by_session.end()) {
91 // First time we see this session: anchor on its first sequence.
92 m_expected_by_session.emplace(key, first_sequence + count);
93 m_messages_seen += count;
94 return 0;
95 }
96
97 std::uint64_t& expected = iter->second;
98 std::uint64_t gap = 0;
99 if (first_sequence > expected) {
100 gap = first_sequence - expected;
101 m_gap_count += gap;
102 if (m_gap_callback) {
103 m_gap_callback(session, expected, first_sequence);
104 }
105 if (m_requester != nullptr) {
106 m_requester->request_retransmit(session, expected, gap);
107 }
108 }
109
110 const std::uint64_t end_sequence = first_sequence + count;
111 if (end_sequence > expected) {
112 // Count only the genuinely new messages, not replayed duplicates.
113 const std::uint64_t already_seen =
114 expected > first_sequence ? expected - first_sequence : 0;
115 m_messages_seen += count - std::min(count, already_seen);
116 expected = end_sequence;
117 }
118 return gap;
119 }
120
123 auto set_gap_callback(GapCallback callback) -> void { m_gap_callback = std::move(callback); }
124
128 auto set_retransmit_requester(RetransmitRequester* requester) noexcept -> void {
129 m_requester = requester;
130 }
131
136 [[nodiscard]] auto expected_next(std::string_view session
137 ) const -> std::optional<std::uint64_t> {
138 const auto iter = m_expected_by_session.find(std::string {session});
139 if (iter == m_expected_by_session.end()) {
140 return std::nullopt;
141 }
142 return iter->second;
143 }
144
147 [[nodiscard]] auto gap_count() const noexcept -> std::uint64_t { return m_gap_count; }
148
151 [[nodiscard]] auto messages_seen() const noexcept -> std::uint64_t { return m_messages_seen; }
152
154 auto reset() -> void {
155 m_expected_by_session.clear();
156 m_gap_count = 0;
157 m_messages_seen = 0;
158 }
159
160 private:
161 std::unordered_map<std::string, std::uint64_t> m_expected_by_session {};
162 GapCallback m_gap_callback {};
163 RetransmitRequester* m_requester {nullptr};
164 std::uint64_t m_gap_count {0};
165 std::uint64_t m_messages_seen {0};
166};
167
168} // namespace itch::transport
Abstract hook a caller implements to drive recovery against a replay or retransmission service when a...
RetransmitRequester(RetransmitRequester &&) noexcept=default
Move-constructs a requester.
RetransmitRequester(const RetransmitRequester &)=default
Copy-constructs a requester.
virtual auto request_retransmit(std::string_view session, std::uint64_t start_sequence, std::uint64_t count) -> void=0
Requests retransmission of count messages starting at sequence start_sequence for the given session.
RetransmitRequester()=default
Constructs a requester with no state.
Tracks per-session sequence numbers across a transport layer and surfaces gaps.
auto gap_count() const noexcept -> std::uint64_t
Total number of missing messages detected across all sessions.
auto reset() -> void
Forgets all per-session state and resets the counters.
std::function< void(std::string_view session, std::uint64_t expected, std::uint64_t received)> GapCallback
Invoked once per detected gap with the session, the sequence the tracker expected,...
auto observe(std::string_view session, std::uint64_t first_sequence, std::uint64_t count) -> std::uint64_t
Records that a packet beginning at first_sequence carried count sequenced messages for session.
auto expected_next(std::string_view session) const -> std::optional< std::uint64_t >
The next sequence number expected for a session, if it has been seen.
auto set_retransmit_requester(RetransmitRequester *requester) noexcept -> void
Installs a non-owning retransmission hook (nullptr clears it).
auto set_gap_callback(GapCallback callback) -> void
Installs the gap-notification callback (empty clears it).
auto messages_seen() const noexcept -> std::uint64_t
Total number of distinct sequenced messages observed.