Loading...
Searching...
No Matches
readWriteIterator.h
Go to the documentation of this file.
1//
2// Copyright 2025 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_EXEC_VDF_READ_WRITE_ITERATOR_H
8#define PXR_EXEC_VDF_READ_WRITE_ITERATOR_H
9
11
12#include "pxr/pxr.h"
13
14#include "pxr/exec/vdf/allocateBoxedValue.h"
15#include "pxr/exec/vdf/boxedContainer.h"
16#include "pxr/exec/vdf/input.h"
18#include "pxr/exec/vdf/mask.h"
19#include "pxr/exec/vdf/node.h"
20#include "pxr/exec/vdf/vector.h"
21
22#include <memory>
23
24PXR_NAMESPACE_OPEN_SCOPE
25
53template<typename T>
55{
56public:
57
60 using value_type = T;
61
64 using difference_type = int;
65
69
73
76 using iterator_category = std::forward_iterator_tag;
77
84 VdfReadWriteIterator(const VdfContext &context, const TfToken &name);
85
90 explicit VdfReadWriteIterator(const VdfContext &context) :
92 {}
93
105 const VdfContext &context,
106 const TfToken &name,
107 size_t count);
108
118 const VdfContext &context,
119 size_t count);
120
123 bool operator==(const VdfReadWriteIterator &rhs) const;
124
127 bool operator!=(const VdfReadWriteIterator &rhs) const {
128 return !operator==(rhs);
129 }
130
135
140 TF_DEV_AXIOM( !IsAtEnd() );
141 TF_DEV_AXIOM( *_iterator < _accessor.GetNumValues() );
142 return _accessor[*_iterator];
143 }
144
149 TF_DEV_AXIOM( !IsAtEnd() );
150 TF_DEV_AXIOM( *_iterator < _accessor.GetNumValues() );
151 return &_accessor[*_iterator];
152 }
153
156 bool IsAtEnd() const {
157 return _iterator.IsAtEnd();
158 }
159
163 _iterator = VdfMask::Bits::AllSetView::const_iterator();
164 }
165
166private:
167
168 // Default constructs a read/write iterator that is at end.
169 VdfReadWriteIterator() : _output(nullptr) {}
170
171 // Returns the current index into the data source.
172 friend int Vdf_GetIteratorIndex(const VdfReadWriteIterator &it) {
173 return *it._iterator;
174 }
175
176 // Initialize the iterator.
177 void _Initialize(const VdfContext &context);
178
179 // The output data accessor.
181
182 // The mask iterator. Will iterate over the affects mask or the optional
183 // bitset.
184 VdfMask::Bits::AllSetView::const_iterator _iterator;
185
186 // The optional bitset used for iteration over values with an empty
187 // affects mask. A bitset is used instead of a mask, in order to avoid
188 // contention on the mask registry lock.
189 std::shared_ptr<VdfMask::Bits> _bits;
190
191 // The source output.
192 const VdfOutput *_output;
193
194};
195
197
198template<typename T>
200 const VdfContext &context,
201 const TfToken &name)
202{
203 // Get the required output, if available. This will issue a coding error if
204 // the output is not available.
205 _output = _GetRequiredOutputForWriting(context, name);
206
207 // Initialize with the required output.
208 if (_output) {
209 _Initialize(context);
210 }
211}
212
213template<typename T>
216 const VdfContext &context,
217 const TfToken &name,
218 size_t count)
219{
220 return Vdf_AllocateBoxedValue<T>(context, name, count)
221 ? VdfReadWriteIterator(context, name)
223}
224
225template<typename T>
228 const VdfContext &context,
229 size_t count)
230{
231 return Vdf_AllocateBoxedValue<T>(context, TfToken(), count)
232 ? VdfReadWriteIterator(context)
234}
235
236template<typename T>
237bool
239{
240 // The source outputs must match.
241 if (_output != rhs._output) {
242 return false;
243 }
244
245 // If either one iterate is at-end, the other one must be at-end too.
246 const bool atEnd = IsAtEnd();
247 const bool rhsAtEnd = rhs.IsAtEnd();
248 if (atEnd || rhsAtEnd) {
249 return atEnd == rhsAtEnd;
250 }
251
252 // If neither iterator is at-end, we can dereference the mask iterators and
253 // compare the resulting indices.
254 return *_iterator == *rhs._iterator;
255}
256
257template<typename T>
260{
261 ++_iterator;
262 return *this;
263}
264
265template<typename T>
266void
268{
269 // Retrieve the affects and request masks.
270 const VdfMask *requestMask = nullptr;
271 const VdfMask *affectsMask = nullptr;
272 if (!_GetOutputMasks(context, *_output, &requestMask, &affectsMask)) {
273 return;
274 }
275
276 // Get the output value for writing. We always expect there to be one. It
277 // should have been prepared by the executor engine.
278 VdfVector *v = _GetOutputValueForWriting(context, *_output);
279 if (!TF_VERIFY(
280 v, "Output '%s' is missing buffer.",
281 _output->GetName().GetText())) {
282 return;
283 }
284
285 // Get the accessor to the data, and bail out if there is no data to
286 // iterate over.
287 _accessor = v->GetReadWriteAccessor<T>();
288 if (_accessor.IsEmpty()) {
289 return;
290 }
291
292 // If the affects mask size mismatches the number of data elements, iterate
293 // over all of the available data. This includes the case where the affects
294 // mask is empty (output does not have an affects mask) and where the value
295 // is boxed.
296 if (ARCH_UNLIKELY(affectsMask->GetSize() != _accessor.GetNumValues())) {
298 (affectsMask->IsEmpty()) ||
299 (affectsMask->GetSize() == 1 && _accessor.IsBoxed()));
300
301 _bits = std::make_shared<VdfMask::Bits>(_accessor.GetNumValues());
302 _bits->Complement();
303 _iterator = _bits->GetAllSetView().begin();
304 }
305
306 // If there is a valid affects mask, let's use it for iteration.
307 else {
308 _iterator = affectsMask->GetBits().GetAllSetView().begin();
309 }
310}
311
312PXR_NAMESPACE_CLOSE_SCOPE
313
314#endif
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:71
A context is the parameter bundle passed to callbacks of computations.
Definition: context.h:40
Base class for libVdf iterators.
Definition: iterator.h:36
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:37
size_t GetSize() const
Returns the size of the mask.
Definition: mask.h:158
bool IsEmpty() const
Returns true if this mask is empty, i.e.
Definition: mask.h:168
VdfMask::Bits const & GetBits() const
Get this mask's content as CtCompressedfBits.
Definition: mask.h:556
A VdfOutput represents an output on a node.
Definition: output.h:32
This iterator provides read access to input values, and write access to the associated output values.
int difference_type
The type used to identify distance between instances of this iterator.
bool IsAtEnd() const
Returns true if the iterator is done iterating and false otherwise.
void AdvanceToEnd()
Advance the iterator to the end.
static VdfReadWriteIterator Allocate(const VdfContext &context, const TfToken &name, size_t count)
Allocates storage for count elements at the given input or output and returns a read/write iterator a...
VdfReadWriteIterator & operator++()
Increment operator to point to the next element.
std::forward_iterator_tag iterator_category
The STL category of this iterator type.
value_type * pointer
The type of a pointer to a value of this iterator.
VdfReadWriteIterator(const VdfContext &context)
Constructs a read/write iterator for the only output on the current node.
bool operator==(const VdfReadWriteIterator &rhs) const
Returns true if this iterator and rhs compare equal.
value_type & reference
Type of a reference to a value of this iterator.
reference operator*() const
Returns reference to current element.
bool operator!=(const VdfReadWriteIterator &rhs) const
Returns true if this iterator and rhs do not compare equal.
pointer operator->() const
Returns pointer to current element.
T value_type
Type of the elements this iterator gives access to.
A read/write accessor for low-level access to the contents of the VdfVector.
Definition: vector.h:403
size_t GetNumValues() const
Returns the size of the vector, i.e.
Definition: vector.h:416
This class is used to abstract away knowledge of the cache data used for each node.
Definition: vector.h:56
ReadWriteAccessor< TYPE > GetReadWriteAccessor() const
GetReadWriteAccessor() allows low level access to the content of the VdfVector via the Vdf_VectorData...
Definition: vector.h:449
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:205
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.
Definition: diagnostic.h:266