MOAB: Mesh Oriented datABase
(version 5.4.1)
|
A resilient iterator is one that can deal with modifications to the container it is iterating over.
A common concern about an iterator is how it behaves when the container over which it is iterating is modified. For example, in STL, iterators for std::set<> and std::map<> and std::list<> containers are guaranteed to work in the presence of modifications to the associated containers with one exception; they don't handle the case when the container member the iterator is currently pointed at is deleted. However, iterators for std::vector<> are not guaranteed to work under any kinds of modification.
In the ITAPS interfaces, a resilient iterator is one that makes certain guarantees (described below) about how it behaves when the container being iterated is modified. On the other hand, a non-resilient is one that does not make such guarantees.
In all cases, the container associated with an iterator in the ITAPS interfaces is an entity set of some sort. This is the only container type for which iterators are defined.
Here, we characterize the behavior of iterators in the presence of container modifications. There are a number of (subtle) aspects to keep in mind.
1. There are set-type (duplicate preventing) sets and list-type (order preserving) sets and iterators behave differently for each.
2. Sets can have set members and entity members. However, iterators are currently defined to iterate over only the entity members. That said, the question arises as to whether modifications that involve only set members nonetheless effect iterator behavior.
3. There are array-type iterators that upon each step in the iteration return a whole array of entity member handles and single entity iterators that upon each step return just a single entity member handle.
4. The iterators support type/topology filtering. Iterators do not (always) strictly iterate over all entities in a set; just all entities matching the type/topology criteria. When type/topology specifies either all types or all topologies, then indeed the iterator will iterate over all entities.
5. There are add/remove operations that add/remove entity members or set members to a set.
6. There are create/delete operations that create and delete entities from the whole iMesh_Instance.
7. There are create/destroy operations that create and destroy sets from the whole interface instance.
8. There is the root set which is special and may have different iterator behavior than all other sets. By definition, the root set is a set-type (duplicate prevent) set.
Modification means addition/removal and/or create/destroy and/or create/delete after iterator initialization. When we talk about container modification here, we are talking about any of the following operations.
A. addition and removal of entity members
void iMesh_rmvEntFromSet(iMesh_Instance instance, void iMesh_rmvEntArrFromSet(iMesh_Instance instance, void iMesh_addEntToSet(iMesh_Instance instance, void iMesh_addEntArrToSet(iMesh_Instance instance,
B. addition and removal of set members
void iMesh_rmvEntSet(iMesh_Instance instance, void iMesh_addEntSet(iMesh_Instance instance,
C. deletion of entities from whole iMesh_Instance
void iMesh_deleteEntArr(iMesh_Instance instance, void iMesh_deleteEnt(iMesh_Instance instance,
D. creation of entities (effects root set)
void iMesh_createEntSet(iMesh_Instance instance, void iMesh_createVtxArr(iMesh_Instance instance, void iMesh_createEntArr(iMesh_Instance instance, void iMesh_createVtx(iMesh_Instance instance, void iMesh_createEnt(iMesh_Instance instance,
E. destruction of entity sets
void iMesh_destroyEntSet(iMesh_Instance instance,
By container modification, we mean that of the above operations occur on the container between iterator initialization and reset.
For purposes of this discussion, there is no distinction between any of these kinds of modifications. What is true for any is true for all. Below, the words add and remove are used to represent any of the modifications that add members or remove members regardless of the kind of operation above.
Resilient iterators are not effected by modifications involving set members:
Iterators are currently defined to iterate over *only* the entity members of a container. In particular, if the container is modified by adding/removing sets from the container, this will have no impact on the iterator. This is true for set-type sets and list-type sets.
Resilient iterator's current position not effected by modification:
If the container is modified, the iterator will continue to properly keep track of the member it was currently pointing at. If a modification occurs that removes the member it was currently pointing at, the iterator will be advanced to the next (not already deleted) member it would have proceeded to. In this way, the iterator is guaranteed to always point at a valid member or to the end of the set, in the case that the member being removed is the last one.
A resilient iterator must skip over removed members:
If the container is modified by removing members, the iterator will guarantee not to land on (e.g. return) those members as iteration proceeds. This is true of set-type sets and list-type sets.
A resilient iterator on set-type sets may fail to return added members:
If the container is a set-type (duplicate preventing) container and it is modified by adding members, the iterator may skip over (e.g. fail to return) members that have been added. In other words, there is no guarantee in this circumstance that an iterator will return added members.
A resilient iterator on list-type sets must return added members. If it is a list-type (order preserving) container, then the iterator must guarantee to return the added members.
A non-resilient iterator may or may not behave like a resilient iterator in some or all of the circumstances described above. There are no guarantees about how a non-resilient iterator will behave. The behavior of a non-resilient iterator in the presence of container modifications is left entirely up to the implementation.
If upon initializing an iterator, an application requests it be resilient and the implementation is unable to support that, the iterator initialization request shall fail and return error iBase_NOT_SUPPORTED.