1414#include " Framework/DataRef.h"
1515#include < functional>
1616
17- extern template class std ::function<o2::framework::DataRef(size_t )>;
18- extern template class std ::function<o2::framework::DataRef (size_t , size_t )>;
17+ extern template class std ::function<o2::framework::DataRef(size_t , o2::framework::DataRefIndices )>;
18+ extern template class std ::function<o2::framework::DataRefIndices (size_t , o2::framework::DataRefIndices )>;
1919
2020namespace o2 ::framework
2121{
@@ -32,37 +32,48 @@ class InputSpan
3232 InputSpan (InputSpan const &) = delete ;
3333 InputSpan (InputSpan&&) = default ;
3434
35- // / @a getter is the mapping between an element of the span referred by
36- // / index and the buffer associated.
37- // / @a size is the number of elements in the span.
38- InputSpan (std::function<DataRef(size_t )> getter, size_t size);
35+ // / Navigate the message store via the DataRefIndices protocol.
36+ // / get_next_pair (DataModelViews.h) provides O(1) sequential advancement for nextIndicesGetter.
37+ InputSpan (std::function<size_t (size_t )> nofPartsGetter,
38+ std::function<int (size_t )> refCountGetter,
39+ std::function<DataRef(size_t , DataRefIndices)> indicesGetter,
40+ std::function<DataRefIndices(size_t , DataRefIndices)> nextIndicesGetter,
41+ size_t size);
3942
40- // / @a getter is the mapping between an element of the span referred by
41- // / index and the buffer associated.
42- // / @a size is the number of elements in the span.
43- InputSpan (std::function<DataRef(size_t , size_t )> getter, size_t size);
43+ // / @a i-th element of the InputSpan (O(partidx) sequential scan via indices protocol)
44+ [[nodiscard]] DataRef get (size_t i, size_t partidx = 0 ) const
45+ {
46+ DataRefIndices idx{0 , 1 };
47+ for (size_t p = 0 ; p < partidx; ++p) {
48+ idx = mNextIndicesGetter (i, idx);
49+ }
50+ return mIndicesGetter (i, idx);
51+ }
4452
45- // / @a getter is the mapping between an element of the span referred by
46- // / index and the buffer associated.
47- // / @nofPartsGetter is the getter for the number of parts associated with an index
48- // / @a size is the number of elements in the span.
49- InputSpan (std::function<DataRef( size_t , size_t )> getter, std::function< size_t ( size_t )> nofPartsGetter, std::function< int ( size_t )> refCountGetter, size_t size);
53+ // / Return the DataRef for the part described by @a indices in slot @a slotIdx in O(1).
54+ [[nodiscard]] DataRef getAtIndices ( size_t slotIdx, DataRefIndices indices) const
55+ {
56+ return mIndicesGetter (slotIdx, indices);
57+ }
5058
51- // / @a i-th element of the InputSpan
52- [[nodiscard]] DataRef get (size_t i, size_t partidx = 0 ) const
59+ // / Advance from @a current to the indices of the next part in slot @a slotIdx in O(1).
60+ [[nodiscard]] DataRefIndices nextIndices (size_t slotIdx, DataRefIndices current ) const
5361 {
54- return mGetter (i, partidx );
62+ return mNextIndicesGetter (slotIdx, current );
5563 }
5664
65+ // --- slot-level Iterator protocol (headerIdx doubles as slot position) ---
66+ [[nodiscard]] DataRefIndices initialIndices () const { return {0 , 0 }; }
67+ [[nodiscard]] DataRefIndices endIndices () const { return {mSize , 0 }; }
68+ [[nodiscard]] DataRef getAtIndices (DataRefIndices indices) const { return mIndicesGetter (indices.headerIdx , {0 , 1 }); }
69+ [[nodiscard]] DataRefIndices nextIndices (DataRefIndices current) const { return {current.headerIdx + 1 , 0 }; }
70+
5771 // / @a number of parts in the i-th element of the InputSpan
5872 [[nodiscard]] size_t getNofParts (size_t i) const
5973 {
6074 if (i >= mSize ) {
6175 return 0 ;
6276 }
63- if (!mNofPartsGetter ) {
64- return 1 ;
65- }
6677 return mNofPartsGetter (i);
6778 }
6879
@@ -94,7 +105,8 @@ class InputSpan
94105 return get (i).payload ;
95106 }
96107
97- // / an iterator class working on position within the a parent class
108+ // / An iterator over the elements of a parent container using the DataRefIndices protocol.
109+ // / ParentT must provide: initialIndices(), getAtIndices(DataRefIndices), nextIndices(DataRefIndices).
98110 template <typename ParentT, typename T>
99111 class Iterator
100112 {
@@ -110,23 +122,23 @@ class InputSpan
110122
111123 Iterator () = delete ;
112124
113- Iterator (ParentType const * parent, size_t position = 0 , size_t size = 0 )
114- : mPosition (position), mSize (size > position ? size : position), mParent (parent), mElement {}
125+ Iterator (ParentType const * parent, bool isEnd = false )
126+ : mParent (parent),
127+ mCurrentIndices (isEnd ? parent->endIndices () : parent->initialIndices()),
128+ mElement{}
115129 {
116- if (mPosition < mSize ) {
117- mElement = mParent ->get ( mPosition );
130+ if (mCurrentIndices != mParent -> endIndices () ) {
131+ mElement = mParent ->getAtIndices ( mCurrentIndices );
118132 }
119133 }
120134
121- ~Iterator () = default ;
122-
123135 // prefix increment
124136 SelfType& operator ++()
125137 {
126- if (mPosition < mSize && ++mPosition < mSize ) {
127- mElement = mParent ->get (mPosition );
138+ mCurrentIndices = mParent ->nextIndices (mCurrentIndices );
139+ if (mCurrentIndices != mParent ->endIndices ()) {
140+ mElement = mParent ->getAtIndices (mCurrentIndices );
128141 } else {
129- // reset the element to the default value of the type
130142 mElement = ElementType{};
131143 }
132144 return *this ;
@@ -145,16 +157,14 @@ class InputSpan
145157 return mElement ;
146158 }
147159
148- // comparison
149160 bool operator ==(const SelfType& rh) const
150161 {
151- return mPosition == rh.mPosition ;
162+ return mCurrentIndices == rh.mCurrentIndices ;
152163 }
153164
154- // comparison
155- bool operator !=(const SelfType& rh) const
165+ auto operator <=>(const SelfType& rh) const
156166 {
157- return mPosition != rh.mPosition ;
167+ return mCurrentIndices <=> rh.mCurrentIndices ;
158168 }
159169
160170 // return pointer to parent instance
@@ -163,22 +173,21 @@ class InputSpan
163173 return mParent ;
164174 }
165175
166- // return current position
176+ // return current position (headerIdx serves as the slot index for slot-level iteration)
167177 [[nodiscard]] size_t position () const
168178 {
169- return mPosition ;
179+ return mCurrentIndices . headerIdx ;
170180 }
171181
172182 private:
173- size_t mPosition ;
174- size_t mSize ;
175183 ParentType const * mParent ;
184+ DataRefIndices mCurrentIndices ;
176185 ElementType mElement ;
177186 };
178187
179188 // / @class InputSpanIterator
180- // / An iterator over the input slots
181- // / It supports an iterator interface to access the parts in the slot
189+ // / An iterator over the input slots.
190+ // / It supports an iterator interface to access the parts in the slot.
182191 template <typename T>
183192 class InputSpanIterator : public Iterator <InputSpan, T>
184193 {
@@ -192,24 +201,26 @@ class InputSpan
192201 using iterator = Iterator<SelfType, T>;
193202 using const_iterator = Iterator<SelfType, const T>;
194203
195- InputSpanIterator (InputSpan const * parent, size_t position = 0 , size_t size = 0 )
196- : BaseType(parent, position, size )
204+ InputSpanIterator (InputSpan const * parent, bool isEnd = false )
205+ : BaseType(parent, isEnd )
197206 {
198207 }
199208
200- // / Get element at {slotindex, partindex}
201- [[nodiscard]] ElementType get (size_t pos) const
209+ // / Initial indices for part-level iteration: first part starts at {headerIdx=0, payloadIdx=1}.
210+ [[nodiscard]] DataRefIndices initialIndices () const { return {0 , 1 }; }
211+ // / Sentinel used by nextIndicesGetter to signal end-of-slot.
212+ [[nodiscard]] DataRefIndices endIndices () const { return {size_t (-1 ), size_t (-1 )}; }
213+
214+ // / Get element at the given raw message indices in O(1).
215+ [[nodiscard]] ElementType getAtIndices (DataRefIndices indices) const
202216 {
203- return this ->parent ()->get (this ->position (), pos );
217+ return this ->parent ()->getAtIndices (this ->position (), indices );
204218 }
205219
206- // / Check if slot is valid, index of part is not used
207- [[nodiscard]] bool isValid ( size_t = 0 ) const
220+ // / Advance @a current to the next part's indices in O(1).
221+ [[nodiscard]] DataRefIndices nextIndices (DataRefIndices current ) const
208222 {
209- if (this ->position () < this ->parent ()->size ()) {
210- return this ->parent ()->isValid (this ->position ());
211- }
212- return false ;
223+ return this ->parent ()->nextIndices (this ->position (), current);
213224 }
214225
215226 // / Get number of parts in input slot
@@ -218,15 +229,14 @@ class InputSpan
218229 return this ->parent ()->getNofParts (this ->position ());
219230 }
220231
221- // iterator for the part access
222232 [[nodiscard]] const_iterator begin () const
223233 {
224- return const_iterator (this , 0 , size ());
234+ return const_iterator (this , size () == 0 );
225235 }
226236
227237 [[nodiscard]] const_iterator end () const
228238 {
229- return const_iterator (this , size () );
239+ return const_iterator (this , true );
230240 }
231241 };
232242
@@ -236,19 +246,19 @@ class InputSpan
236246 // supporting read-only access and returning const_iterator
237247 [[nodiscard]] const_iterator begin () const
238248 {
239- return {this , 0 , size () };
249+ return {this , false };
240250 }
241251
242- // supporting read-only access and returning const_iterator
243252 [[nodiscard]] const_iterator end () const
244253 {
245- return {this , size () };
254+ return {this , true };
246255 }
247256
248257 private:
249- std::function<DataRef(size_t , size_t )> mGetter ;
250258 std::function<size_t (size_t )> mNofPartsGetter ;
251259 std::function<int (size_t )> mRefCountGetter ;
260+ std::function<DataRef(size_t , DataRefIndices)> mIndicesGetter ;
261+ std::function<DataRefIndices(size_t , DataRefIndices)> mNextIndicesGetter ;
252262 size_t mSize ;
253263};
254264
0 commit comments