Branch data Line data Source code
1 : : /*
2 : : * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 : : * storing and accessing finite element mesh data.
4 : : *
5 : : * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 : : * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7 : : * retains certain rights in this software.
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : */
15 : :
16 : : /**\file RangeSeqIntersectIter.hpp
17 : : *\author Jason Kraftcheck ([email protected])
18 : : *\date 2006-08-11
19 : : *\date 2007-11-06
20 : : */
21 : :
22 : : #ifndef MB_RANGE_SEQ_INTERSECT_ITER_HPP
23 : : #define MB_RANGE_SEQ_INTERSECT_ITER_HPP
24 : :
25 : : #include "moab/Types.hpp"
26 : : #include "moab/Range.hpp"
27 : :
28 : : namespace moab
29 : : {
30 : :
31 : : class SequenceManager;
32 : : class EntitySequence;
33 : :
34 : : #define MB_RANGE_SEQ_INTERSECT_ITER_STATS 0
35 : :
36 : : /** \brief Iterate over the blocks of EntityHandles in an Range that
37 : : * are in the same EntitySequence.
38 : : *
39 : : * Iterate over an Range, returning blocks of entities that are the
40 : : * largest ranges of contiguous handles that meet one of the following
41 : : * conditions:
42 : : * - All are valid handles belonging to the same EntitySequence
43 : : * - All are invalid handles of the same EntityType
44 : : *
45 : : * The return type from init() or step() indicates whether or not the
46 : : * current range contains valid entities. If the handles are either
47 : : * all valid or all holes in an EntitySequence, that sequence can
48 : : * be obtained with get_sequence(). get_sequence() will return NULL if
49 : : * there is no corresponding EntitySequence for the block of handles.
50 : : *
51 : : * This class keeps a data related to the 'current' EntitySequence and
52 : : * references to the Range pasesd to init(). Changing either of these
53 : : * while an instance of this class is in use would be bad.
54 : : */
55 : : class RangeSeqIntersectIter
56 : : {
57 : : public:
58 : 1160 : RangeSeqIntersectIter( SequenceManager* sequences )
59 : 1160 : : mSequenceManager( sequences ), mSequence( 0 ), mStartHandle( 0 ), mEndHandle( 0 ), mLastHandle( 0 )
60 : : {
61 : 1160 : }
62 : :
63 : : /** Initialize iterator to first valid subset
64 : : *\return - MB_SUCCESS : initial position of iterator is valid
65 : : * - MB_ENITITY_NOT_FOUND : range contains invalid handle -- can step past by calling
66 : : *again
67 : : * - MB_FAILURE : No entities (start == end)
68 : : */
69 : : ErrorCode init( Range::const_iterator start, Range::const_iterator end );
70 : :
71 : : /** Step iterator to next range.
72 : : *\return - MB_SUCCESS : there is another range, and iter has been changed to it
73 : : * - MB_ENITITY_NOT_FOUND : range contains invalid handle -- can step past by calling
74 : : *again
75 : : * - MB_FAILURE : at end.
76 : : */
77 : : ErrorCode step();
78 : :
79 : : /**\brief Check if next call to step() will return MB_FAILURE.
80 : : *
81 : : * Check if the iterator cannot be advanced any further.
82 : : * If this method returns true, then the *next* call to step()
83 : : * will return MB_FAILURE.
84 : : */
85 : 3449 : bool is_at_end() const
86 : : {
87 : 3449 : return mEndHandle == mLastHandle;
88 : : }
89 : :
90 : : /** Get the EntitySequence for the current block.
91 : : * May be NULL for invaild handles.
92 : : */
93 : 3463 : EntitySequence* get_sequence() const
94 : : {
95 : 3463 : return mSequence;
96 : : }
97 : :
98 : : /** Get first handle in block */
99 : 11483 : EntityHandle get_start_handle() const
100 : : {
101 : 11483 : return mStartHandle;
102 : : }
103 : :
104 : : /** Get last handle in block */
105 : 6831 : EntityHandle get_end_handle() const
106 : : {
107 : 6831 : return mEndHandle;
108 : : }
109 : :
110 : : #if MB_RANGE_SEQ_INTERSECT_ITER_STATS
111 : : static double fragmentation()
112 : : {
113 : : return ( doubleNumCalls + intNumCalls ) / ( doubleEntCount + intEntCount );
114 : : }
115 : : #endif
116 : :
117 : : private:
118 : : /** Update entity sequence data (mSequence and freeIndex) for current
119 : : * mStartHandle. If mEndHandle is past end of sequence, trim it.
120 : : * Called by step() and init(). step() handles iterating over the pairs
121 : : * in the Range. This method handles iterating over the set of
122 : : * EntitySequences that intersect the pair.
123 : : */
124 : : ErrorCode update_entity_sequence();
125 : :
126 : : /** Handle error case where we encountered an EntityHandle w/out
127 : : * a corresponding EntitySequence. Trim mEndHandle such that it
128 : : * is before the next valid EntityHandle of the same type.
129 : : *\return Always returns MB_ENTITY_NOT_FOUND
130 : : */
131 : : ErrorCode find_invalid_range();
132 : :
133 : : SequenceManager* mSequenceManager; //!< THE EntitySequenceManager
134 : : EntitySequence* mSequence; //!< EntitySequence corresponding to current location
135 : : Range::const_pair_iterator rangeIter; //!< Current position in Range.
136 : : EntityHandle mStartHandle, mEndHandle; //!< Subset of current EntitySequence
137 : : EntityHandle mLastHandle; //!< The last of the list of all handles in the Range
138 : :
139 : : #if MB_RANGE_SEQ_INTERSECT_ITER_STATS
140 : : static double doubleNumCalls, doubleEntCount;
141 : : static unsigned long intNumCalls, intEntCount;
142 : : static void update_stats( unsigned long num_ents );
143 : : #endif
144 : : };
145 : :
146 : : } // namespace moab
147 : :
148 : : #endif
|