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.cpp
17 : : *\author Jason Kraftcheck ([email protected])
18 : : *\date 2006-08-11
19 : : */
20 : :
21 : : #include "RangeSeqIntersectIter.hpp"
22 : : #include "SequenceManager.hpp"
23 : : #include "EntitySequence.hpp"
24 : : #include <assert.h>
25 : :
26 : : namespace moab
27 : : {
28 : :
29 : 1167 : ErrorCode RangeSeqIntersectIter::init( Range::const_iterator start, Range::const_iterator end )
30 : : {
31 : 1167 : mSequence = 0;
32 : 1167 : rangeIter = start;
33 : :
34 : : // special case : nothing to iterate over
35 [ - + ]: 1167 : if( start == end )
36 : : {
37 : 0 : mStartHandle = mEndHandle = mLastHandle = 0;
38 : 0 : return MB_FAILURE;
39 : : }
40 : :
41 : : // normal case
42 : 1167 : mStartHandle = *start;
43 : 1167 : --end;
44 : 1167 : mLastHandle = *end;
45 : 1167 : mEndHandle = ( *rangeIter ).second;
46 [ + + ]: 1167 : if( mEndHandle > mLastHandle ) mEndHandle = mLastHandle;
47 : :
48 : : #if MB_RANGE_SEQ_INTERSECT_ITER_STATS
49 : : ErrorCode result = update_entity_sequence();
50 : : update_stats( mEndHandle - mStartHandle + 1 );
51 : : return result;
52 : : #else
53 : 1167 : return update_entity_sequence();
54 : : #endif
55 : : }
56 : :
57 : 3441 : ErrorCode RangeSeqIntersectIter::step()
58 : : {
59 : : // If at end, return MB_FAILURE
60 [ + + ]: 3441 : if( is_at_end() ) return MB_FAILURE;
61 : : // If the last block was at the end of the rangeIter pair,
62 : : // then advance the iterator and set the next block
63 [ + + ]: 2272 : else if( mEndHandle == ( *rangeIter ).second )
64 : : {
65 : 2222 : ++rangeIter;
66 : 2222 : mStartHandle = ( *rangeIter ).first;
67 : : }
68 : : // Otherwise start with next entity in the pair
69 : : else
70 : : {
71 : 50 : mStartHandle = mEndHandle + 1;
72 : : }
73 : : // Always take the remaining entities in the rangeIter pair.
74 : : // will trim up the end of the range in update_entity_sequence().
75 : 2272 : mEndHandle = ( *rangeIter ).second;
76 [ - + ]: 2272 : if( mEndHandle > mLastHandle ) mEndHandle = mLastHandle;
77 : :
78 : : // Now trim up the range (decrease mEndHandle) as necessary
79 : : // for the corresponding EntitySquence
80 : : #if MB_RANGE_SEQ_INTERSECT_ITER_STATS
81 : : ErrorCode result = update_entity_sequence();
82 : : update_stats( mEndHandle - mStartHandle + 1 );
83 : : return result;
84 : : #else
85 : 2272 : return update_entity_sequence();
86 : : #endif
87 : : }
88 : :
89 : 3439 : ErrorCode RangeSeqIntersectIter::update_entity_sequence()
90 : : {
91 : : // mStartHandle to mEndHandle is a subset of the Range.
92 : : // Update sequence data as necessary and trim that subset
93 : : // (reduce mEndHandle) for the current EntitySequence.
94 : :
95 : : // Need to update the sequence pointer?
96 [ + + ][ + + ]: 3439 : if( !mSequence || mStartHandle > mSequence->end_handle() )
[ + + ]
97 : : {
98 : :
99 : : // Check that the mStartHandle is valid
100 [ - + ]: 1354 : if( TYPE_FROM_HANDLE( mStartHandle ) >= MBMAXTYPE ) return MB_TYPE_OUT_OF_RANGE;
101 : :
102 [ + + ]: 1354 : if( MB_SUCCESS != mSequenceManager->find( mStartHandle, mSequence ) ) return find_invalid_range();
103 : : }
104 : :
105 : : // if mEndHandle is past end of sequence or block of used
106 : : // handles within sequence, shorten it.
107 [ + + ]: 3430 : if( mEndHandle > mSequence->end_handle() ) mEndHandle = mSequence->end_handle();
108 : :
109 : 3430 : return MB_SUCCESS;
110 : : }
111 : :
112 : 9 : ErrorCode RangeSeqIntersectIter::find_invalid_range()
113 : : {
114 [ - + ]: 9 : assert( !mSequence );
115 : :
116 : : // no more entities in current range
117 [ + + ]: 9 : if( mStartHandle == mEndHandle ) return MB_ENTITY_NOT_FOUND;
118 : :
119 : : // Find the next EntitySequence
120 [ + - ]: 7 : EntityType type = TYPE_FROM_HANDLE( mStartHandle );
121 [ + - ]: 7 : const TypeSequenceManager& map = mSequenceManager->entity_map( type );
122 [ + - ]: 7 : TypeSequenceManager::const_iterator iter = map.upper_bound( mStartHandle );
123 : : // If no next sequence of the same type
124 [ + - ][ + - ]: 7 : if( iter == map.end() )
[ + + ]
125 : : {
126 : : // If end type not the same as start type, split on type
127 [ + - ][ + - ]: 1 : if( type != TYPE_FROM_HANDLE( mEndHandle ) )
128 : : {
129 : : int junk;
130 [ + - ]: 1 : mEndHandle = CREATE_HANDLE( type, MB_END_ID, junk );
131 : : }
132 : : }
133 : : // otherwise invalid range ends at min(mEndHandle, sequence start handle - 1)
134 [ + - ][ + - ]: 6 : else if( ( *iter )->start_handle() <= mEndHandle )
[ + - ]
135 : : {
136 [ + - ][ + - ]: 6 : mEndHandle = ( *iter )->start_handle() - 1;
137 : : }
138 : :
139 : 9 : return MB_ENTITY_NOT_FOUND;
140 : : }
141 : :
142 : : #if MB_RANGE_SEQ_INTERSECT_ITER_STATS
143 : : double RangeSeqIntersectIter::doubleNumCalls = 0;
144 : : double RangeSeqIntersectIter::doubleEntCount = 0;
145 : : unsigned long RangeSeqIntersectIter::intNumCalls = 0;
146 : : unsigned long RangeSeqIntersectIter::intEntCount = 0;
147 : :
148 : : void RangeSeqIntersectIter::update_stats( unsigned long num_ents )
149 : : {
150 : : if( std::numeric_limits< unsigned long >::max() == intNumCalls )
151 : : {
152 : : doubleNumCalls += intNumCalls;
153 : : intNumCalls = 0;
154 : : }
155 : : ++intNumCalls;
156 : :
157 : : if( std::numeric_limits< unsigned long >::max() - intEntCount > num_ents )
158 : : {
159 : : doubleNumCalls += intEntCount;
160 : : intEntCount = num_ents;
161 : : }
162 : : else
163 : : {
164 : : intEntCount += num_ents;
165 : : }
166 : : }
167 : : #endif
168 : :
169 : : } // namespace moab
|