Skip to content

Commit 4f80bbd

Browse files
committed
DPL: add ability to get next pair
1 parent 2cec687 commit 4f80bbd

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

Framework/Core/include/Framework/DataModelViews.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,43 @@ struct get_pair {
127127
}
128128
};
129129

130+
// Advance from a DataRefIndices to the next one in O(1), reading only the
131+
// current header. Intended for use in iterators so that ++ is O(1) rather
132+
// than the O(n) while-loop that get_pair requires.
133+
//
134+
// New-style block (splitPayloadIndex == splitPayloadParts > 1):
135+
// layout: [header, payload_0, payload_1, ..., payload_{N-1}]
136+
// advance within block while payloads remain, then jump to the next block.
137+
//
138+
// Old-style block (splitPayloadIndex != splitPayloadParts, splitPayloadParts > 1)
139+
// or single pair (splitPayloadParts == 0):
140+
// layout: [header, payload] – always advance by two messages.
141+
struct get_next_pair {
142+
DataRefIndices current;
143+
template <typename R>
144+
requires std::ranges::random_access_range<R> && std::ranges::sized_range<R>
145+
friend DataRefIndices operator|(R&& r, get_next_pair self)
146+
{
147+
size_t hIdx = self.current.headerIdx;
148+
auto* header = o2::header::get<o2::header::DataHeader*>(r[hIdx]->GetData());
149+
if (!header) {
150+
throw std::runtime_error("Not a DataHeader");
151+
}
152+
if (header->splitPayloadParts > 1 && header->splitPayloadIndex == header->splitPayloadParts) {
153+
// New-style block: one header followed by splitPayloadParts contiguous payloads.
154+
if (self.current.payloadIdx < hIdx + header->splitPayloadParts) {
155+
// More sub-payloads remain in this block.
156+
return {hIdx, self.current.payloadIdx + 1};
157+
}
158+
// Last sub-payload consumed; move to the first pair of the next block.
159+
size_t nextHIdx = hIdx + header->splitPayloadParts + 1;
160+
return {nextHIdx, nextHIdx + 1};
161+
}
162+
// Old-style [header, payload] pairs or a single pair: advance by two messages.
163+
return {hIdx + 2, hIdx + 3};
164+
}
165+
};
166+
130167
struct get_dataref_indices {
131168
size_t part;
132169
size_t subPart;

0 commit comments

Comments
 (0)