Project
Loading...
Searching...
No Matches
InputSpan.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef O2_FRAMEWORK_INPUTSPAN_H_
12#define O2_FRAMEWORK_INPUTSPAN_H_
13
14#include "Framework/DataRef.h"
15#include <functional>
16#include <fairmq/FwdDecls.h>
17
18extern template class std::function<o2::framework::DataRef(size_t, o2::framework::DataRefIndices)>;
19extern template class std::function<o2::framework::DataRefIndices(size_t, o2::framework::DataRefIndices)>;
20extern template class std::function<fair::mq::Message*(size_t, o2::framework::DataRefIndices)>;
21
22namespace o2::framework
23{
24
31{
32 public:
33 InputSpan() = delete;
34 InputSpan(InputSpan const&) = delete;
35 InputSpan(InputSpan&&) = default;
36
39 InputSpan(std::function<size_t(size_t)> nofPartsGetter,
40 std::function<int(size_t)> refCountGetter,
41 std::function<DataRef(size_t, DataRefIndices)> indicesGetter,
42 std::function<DataRefIndices(size_t, DataRefIndices)> nextIndicesGetter,
43 std::function<fair::mq::Message*(size_t, DataRefIndices)> payloadGetter,
44 size_t size);
45
47 [[nodiscard]] DataRef get(size_t i, size_t partidx = 0) const
48 {
49 DataRefIndices idx{0, 1};
50 for (size_t p = 0; p < partidx; ++p) {
51 idx = mNextIndicesGetter(i, idx);
52 }
53 return mIndicesGetter(i, idx);
54 }
55
57 [[nodiscard]] DataRef getAtIndices(size_t slotIdx, DataRefIndices indices) const
58 {
59 return mIndicesGetter(slotIdx, indices);
60 }
61
63 [[nodiscard]] fair::mq::Message* getPayloadAtIndices(size_t slotIdx, DataRefIndices indices) const
64 {
65 return mPayloadGetter(slotIdx, indices);
66 }
67
69 [[nodiscard]] DataRefIndices nextIndices(size_t slotIdx, DataRefIndices current) const
70 {
71 return mNextIndicesGetter(slotIdx, current);
72 }
73
74 // --- slot-level Iterator protocol (headerIdx doubles as slot position) ---
75 [[nodiscard]] DataRefIndices initialIndices() const { return {0, 0}; }
76 [[nodiscard]] DataRefIndices endIndices() const { return {mSize, 0}; }
77 [[nodiscard]] DataRef getAtIndices(DataRefIndices indices) const { return mIndicesGetter(indices.headerIdx, {0, 1}); }
78 [[nodiscard]] DataRefIndices nextIndices(DataRefIndices current) const { return {current.headerIdx + 1, 0}; }
79
81 [[nodiscard]] size_t getNofParts(size_t i) const
82 {
83 if (i >= mSize) {
84 return 0;
85 }
86 return mNofPartsGetter(i);
87 }
88
89 // Get the refcount for a given part
90 [[nodiscard]] int getRefCount(size_t i) const
91 {
92 if (i >= mSize) {
93 return 0;
94 }
95 if (!mRefCountGetter) {
96 return -1;
97 }
98 return mRefCountGetter(i);
99 }
100
102 [[nodiscard]] size_t size() const
103 {
104 return mSize;
105 }
106
107 [[nodiscard]] const char* header(size_t i) const
108 {
109 return get(i).header;
110 }
111
112 [[nodiscard]] const char* payload(size_t i) const
113 {
114 return get(i).payload;
115 }
116
119 template <typename ParentT, typename T>
121 {
122 public:
123 using ParentType = ParentT;
125 using iterator_category = std::forward_iterator_tag;
126 using value_type = T;
127 using reference = T&;
128 using pointer = T*;
129 using difference_type = std::ptrdiff_t;
130 using ElementType = typename std::remove_const<value_type>::type;
131
132 Iterator() = delete;
133
134 Iterator(ParentType const* parent, bool isEnd = false)
135 : mParent(parent),
136 mCurrentIndices(isEnd ? parent->endIndices() : parent->initialIndices()),
137 mElement{}
138 {
139 if (mCurrentIndices != mParent->endIndices()) {
140 mElement = mParent->getAtIndices(mCurrentIndices);
141 }
142 }
143
144 // prefix increment
146 {
147 mCurrentIndices = mParent->nextIndices(mCurrentIndices);
148 if (mCurrentIndices != mParent->endIndices()) {
149 mElement = mParent->getAtIndices(mCurrentIndices);
150 } else {
151 mElement = ElementType{};
152 }
153 return *this;
154 }
155 // postfix increment
156 SelfType operator++(int /*unused*/)
157 {
158 SelfType copy(*this);
159 operator++();
160 return copy;
161 }
162
163 // return reference
165 {
166 return mElement;
167 }
168
169 bool operator==(const SelfType& rh) const
170 {
171 return mCurrentIndices == rh.mCurrentIndices;
172 }
173
174 auto operator<=>(const SelfType& rh) const
175 {
176 return mCurrentIndices <=> rh.mCurrentIndices;
177 }
178
179 // return pointer to parent instance
180 [[nodiscard]] ParentType const* parent() const
181 {
182 return mParent;
183 }
184
185 // return current position (headerIdx serves as the slot index for slot-level iteration)
186 [[nodiscard]] size_t position() const
187 {
188 return mCurrentIndices.headerIdx;
189 }
190
191 // return current indices
192 [[nodiscard]] DataRefIndices indices() const
193 {
194 return mCurrentIndices;
195 }
196
197 // return an iterable range over all parts in the current slot
198 // only available for slot-level iterators whose parent has parts(size_t)
199 [[nodiscard]] auto parts() const
200 requires requires(ParentType const* p, size_t i) { p->parts(i); }
201 {
202 return mParent->parts(mCurrentIndices.headerIdx);
203 }
204
205 private:
206 ParentType const* mParent;
207 DataRefIndices mCurrentIndices;
208 ElementType mElement;
209 };
210
212 struct PartRange {
214 size_t slot;
215
216 [[nodiscard]] DataRefIndices initialIndices() const { return {0, 1}; }
217 [[nodiscard]] DataRefIndices endIndices() const { return {size_t(-1), size_t(-1)}; }
218 [[nodiscard]] DataRef getAtIndices(DataRefIndices idx) const { return span->getAtIndices(slot, idx); }
219 [[nodiscard]] fair::mq::Message* getPayloadAtIndices(DataRefIndices idx) const { return span->getPayloadAtIndices(slot, idx); }
220 [[nodiscard]] DataRefIndices nextIndices(DataRefIndices idx) const { return span->nextIndices(slot, idx); }
221 [[nodiscard]] size_t size() const { return span->getNofParts(slot); }
222
223 [[nodiscard]] Iterator<PartRange, const DataRef> begin() const { return {this, size() == 0}; }
224 [[nodiscard]] Iterator<PartRange, const DataRef> end() const { return {this, true}; }
225 };
226
228 [[nodiscard]] PartRange parts(size_t i) const { return {this, i}; }
229
232
233 // supporting read-only access and returning const_iterator
234 [[nodiscard]] const_iterator begin() const
235 {
236 return {this, false};
237 }
238
239 [[nodiscard]] const_iterator end() const
240 {
241 return {this, true};
242 }
243
244 private:
245 std::function<size_t(size_t)> mNofPartsGetter;
246 std::function<int(size_t)> mRefCountGetter;
247 std::function<DataRef(size_t, DataRefIndices)> mIndicesGetter;
248 std::function<DataRefIndices(size_t, DataRefIndices)> mNextIndicesGetter;
249 std::function<fair::mq::Message*(size_t, DataRefIndices)> mPayloadGetter;
250 size_t mSize;
251};
252
253} // namespace o2::framework
254
255#endif // FRAMEWORK_INPUTSSPAN_H
int32_t i
bool operator==(const SelfType &rh) const
Definition InputSpan.h:169
DataRefIndices indices() const
Definition InputSpan.h:192
typename std::remove_const< value_type >::type ElementType
Definition InputSpan.h:130
std::forward_iterator_tag iterator_category
Definition InputSpan.h:125
ParentType const * parent() const
Definition InputSpan.h:180
auto operator<=>(const SelfType &rh) const
Definition InputSpan.h:174
Iterator(ParentType const *parent, bool isEnd=false)
Definition InputSpan.h:134
DataRef getAtIndices(DataRefIndices indices) const
Definition InputSpan.h:77
const char * header(size_t i) const
Definition InputSpan.h:107
const_iterator end() const
Definition InputSpan.h:239
const_iterator begin() const
Definition InputSpan.h:234
DataRefIndices initialIndices() const
Definition InputSpan.h:75
InputSpan(InputSpan const &)=delete
PartRange parts(size_t i) const
Return an iterable range over all parts in slot i.
Definition InputSpan.h:228
DataRef getAtIndices(size_t slotIdx, DataRefIndices indices) const
Return the DataRef for the part described by indices in slot slotIdx in O(1).
Definition InputSpan.h:57
fair::mq::Message * getPayloadAtIndices(size_t slotIdx, DataRefIndices indices) const
Return the payload as fair::mq::Message* for the part described by indices in slot slotIdx.
Definition InputSpan.h:63
size_t size() const
Number of elements in the InputSpan.
Definition InputSpan.h:102
InputSpan(InputSpan &&)=default
DataRefIndices nextIndices(size_t slotIdx, DataRefIndices current) const
Advance from current to the indices of the next part in slot slotIdx in O(1).
Definition InputSpan.h:69
DataRefIndices endIndices() const
Definition InputSpan.h:76
size_t getNofParts(size_t i) const
number of parts in the i-th element of the InputSpan
Definition InputSpan.h:81
DataRef get(size_t i, size_t partidx=0) const
i-th element of the InputSpan (O(partidx) sequential scan via indices protocol)
Definition InputSpan.h:47
const char * payload(size_t i) const
Definition InputSpan.h:112
DataRefIndices nextIndices(DataRefIndices current) const
Definition InputSpan.h:78
int getRefCount(size_t i) const
Definition InputSpan.h:90
GLsizeiptr size
Definition glcorearb.h:659
GLsizei GLenum const void * indices
Definition glcorearb.h:400
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
A range over the parts of a single slot, supporting range-based for.
Definition InputSpan.h:212
DataRefIndices initialIndices() const
Definition InputSpan.h:216
DataRefIndices endIndices() const
Definition InputSpan.h:217
Iterator< PartRange, const DataRef > begin() const
Definition InputSpan.h:223
Iterator< PartRange, const DataRef > end() const
Definition InputSpan.h:224
DataRef getAtIndices(DataRefIndices idx) const
Definition InputSpan.h:218
fair::mq::Message * getPayloadAtIndices(DataRefIndices idx) const
Definition InputSpan.h:219
DataRefIndices nextIndices(DataRefIndices idx) const
Definition InputSpan.h:220