flt.utils.muxer: use a heap to sort iterators (also: rewrite in C++)
[babeltrace.git] / src / plugins / utils / muxer / msg-iter.hpp
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * Copyright 2017-2023 Philippe Proulx <pproulx@efficios.com>
6 */
7
8 #ifndef BABELTRACE_PLUGINS_UTILS_MUXER_MSG_ITER_HPP
9 #define BABELTRACE_PLUGINS_UTILS_MUXER_MSG_ITER_HPP
10
11 #include <vector>
12
13 #include "cpp-common/bt2/optional-borrowed-object.hpp"
14 #include "cpp-common/bt2/plugin-dev.hpp"
15 #include "cpp-common/bt2c/prio-heap.hpp"
16 #include "cpp-common/bt2c/uuid.hpp"
17 #include "cpp-common/bt2s/optional.hpp"
18
19 #include "upstream-msg-iter.hpp"
20
21 namespace bt2mux {
22
23 class Comp;
24
25 class MsgIter final : public bt2::UserMessageIterator<MsgIter, Comp>
26 {
27 friend bt2::UserMessageIterator<MsgIter, Comp>;
28
29 private:
30 /* Clock class nature expectation */
31 enum class _ClkClsExpectation
32 {
33 ANY,
34 NONE,
35 ORIG_IS_UNIX_EPOCH,
36 ORIG_ISNT_UNIX_EPOCH_AND_SPEC_UUID,
37 ORIG_ISNT_UNIX_EPOCH_AND_NO_UUID,
38 };
39
40 /* Comparator for `_mHeap` with its own logger */
41 class _HeapComparator final
42 {
43 public:
44 explicit _HeapComparator(const bt2c::Logger& logger);
45
46 bool operator()(const UpstreamMsgIter *upstreamMsgIterA,
47 const UpstreamMsgIter *upstreamMsgIterB) const noexcept;
48
49 private:
50 bt2c::Logger _mLogger;
51 };
52
53 public:
54 explicit MsgIter(bt2::SelfMessageIterator selfMsgIter,
55 bt2::SelfMessageIteratorConfiguration config,
56 bt2::SelfComponentOutputPort selfPort);
57
58 private:
59 bool _canSeekBeginning();
60 void _seekBeginning();
61 void _next(bt2::ConstMessageArray& msgs);
62
63 /*
64 * Makes sure `_mUpstreamMsgItersToReload` is empty so that `_mHeap`
65 * is ready for the next message selection.
66 *
67 * This may throw whatever UpstreamMsgIter::reload() may throw.
68 */
69 void _ensureFullHeap();
70
71 /*
72 * Validates the clock class of the received message `msg`, setting
73 * the expectation if this is the first one.
74 *
75 * Throws `bt2::Error` on error.
76 */
77 void _validateMsgClkCls(bt2::ConstMessage msg);
78
79 /*
80 * Sets the clock class expectation (`_mClkClsExpectation` and
81 * `_mExpectedClkClsUuid`) according to `clkCls`.
82 */
83 void _setClkClsExpectation(bt2::OptionalBorrowedObject<bt2::ConstClockClass> clkCls) noexcept;
84
85 /*
86 * Checks that `clkCls` meets the current clock class expectation,
87 * throwing if it doesn't.
88 */
89 void _makeSureClkClsIsExpected(bt2::ConstMessage msg,
90 bt2::OptionalBorrowedObject<bt2::ConstClockClass> clkCls) const;
91
92 /*
93 * Container of all the upstream message iterators.
94 *
95 * The only purpose of this is to own them; where they are below
96 * indicates their state.
97 */
98 std::vector<UpstreamMsgIter::UP> _mUpstreamMsgIters;
99
100 /*
101 * Heap of ready-to-use upstream message iterators (pointers to
102 * owned objects in `_mUpstreamMsgIters` above).
103 */
104 bt2c::PrioHeap<UpstreamMsgIter *, _HeapComparator> _mHeap;
105
106 /*
107 * Current upstream message iterators to reload, on which we must
108 * call reload() before moving them to `_mHeap` or to
109 * `_mEndedUpstreamMsgIters`.
110 *
111 * Using `std::vector` instead of some linked list because the
112 * typical scenario is to add a single one and then remove it
113 * shortly after.
114 */
115 std::vector<UpstreamMsgIter *> _mUpstreamMsgItersToReload;
116
117 /*
118 * Which kind of clock class to expect from any incoming message.
119 *
120 * The very first received message determines this for all the
121 * following.
122 *
123 * For `ORIG_ISNT_UNIX_EPOCH_AND_SPEC_UUID`, `*_mExpectedClkClsUuid`
124 * is the expected specific UUID.
125 */
126 _ClkClsExpectation _mClkClsExpectation = _ClkClsExpectation::ANY;
127 bt2s::optional<bt2c::Uuid> _mExpectedClkClsUuid;
128 };
129
130 } /* namespace bt2mux */
131
132 #endif /* BABELTRACE_PLUGINS_UTILS_MUXER_MSG_ITER_HPP */
This page took 0.035838 seconds and 5 git commands to generate.