15 using Timestamp =
long long;
18 std::lock_guard<std::mutex> lock(m_mutex);
21 if (m_fragments.empty()) {
22 m_event_reference_time = fragment.header.timestamp;
25 m_fragments[fragment.header.timestamp].push_back(std::move(fragment));
28 bool has_expired_fragments(Timestamp reference_time,
long long coherence_window_ns) {
29 std::lock_guard<std::mutex> lock(m_mutex);
30 if (m_fragments.empty()) {
33 auto it_oldest = m_fragments.begin();
34 return it_oldest->first < reference_time - coherence_window_ns;
37 Timestamp get_reference_time()
const {
38 std::lock_guard<std::mutex> lock(m_mutex);
39 return m_event_reference_time;
42 bool try_build_event(
long long coherence_window_ns,
int min_subsystems, std::vector<DataFragment>& built_fragments) {
43 std::lock_guard<std::mutex> lock(m_mutex);
44 if (m_fragments.empty())
return false;
47 Timestamp window_ref_time = m_event_reference_time;
49 auto it_begin = m_fragments.lower_bound(window_ref_time - coherence_window_ns);
50 auto it_end = m_fragments.upper_bound(window_ref_time + coherence_window_ns);
52 if (it_begin == it_end)
return false;
54 std::set<uint64_t> subsystems_found;
55 std::vector<Timestamp> timestamps_in_window;
57 for (
auto it = it_begin; it != it_end; ++it) {
58 timestamps_in_window.push_back(it->first);
59 for (
const auto& frag : it->second) {
60 subsystems_found.insert(frag.header.subsystem_id);
66 if (subsystems_found.size() <
static_cast<size_t>(min_subsystems)) {
71 for (Timestamp ts : timestamps_in_window) {
72 for (
auto& frag : m_fragments[ts]) {
73 built_fragments.push_back(std::move(frag));
75 m_fragments.erase(ts);
79 if (!m_fragments.empty()) {
80 m_event_reference_time = m_fragments.begin()->first;
87 std::map<Timestamp, std::vector<DataFragment>> m_fragments;
88 Timestamp m_event_reference_time = 0;
89 mutable std::mutex m_mutex;