Branch data Line data Source code
1 : : #include "TypeSequenceManager.hpp"
2 : : #include "SequenceData.hpp"
3 : : #include "moab/Error.hpp"
4 : : #include <assert.h>
5 : : #include <limits>
6 : :
7 : : namespace moab
8 : : {
9 : :
10 : 10496 : TypeSequenceManager::~TypeSequenceManager()
11 : : {
12 : : // We assume that for there to be multiple sequences referencing
13 : : // the same SequenceData, there must be some portion of the
14 : : // SequenceData that is unused. Otherwise the sequences should
15 : : // have been merged. Given that assumption, it is the case that
16 : : // either a) a SequenceData is in availableList or b) the
17 : : // SequenceData is referenced by exactly one sequence.
18 : :
19 : : // Delete every entity sequence
20 [ + + ]: 7946 : for( iterator i = begin(); i != end(); ++i )
21 : : {
22 : 2698 : EntitySequence* seq = *i;
23 : : // Check for case b) above
24 [ + + ]: 2698 : if( seq->using_entire_data() )
25 : : {
26 : : // Delete sequence before data, because sequence
27 : : // has a pointer to data and may try to dereference
28 : : // that pointer during its destruction.
29 : 506 : SequenceData* data = seq->data();
30 [ + - ]: 506 : delete seq;
31 [ + - ]: 506 : delete data;
32 : : }
33 : : else
34 : : {
35 [ + - ]: 2192 : delete seq;
36 : : }
37 : : }
38 : 5248 : sequenceSet.clear();
39 : :
40 : : // Case a) above
41 [ + + ]: 6169 : for( data_iterator i = availableList.begin(); i != availableList.end(); ++i )
42 [ + - ]: 921 : delete *i;
43 : 5248 : availableList.clear();
44 : 5248 : }
45 : :
46 : 11340 : ErrorCode TypeSequenceManager::merge_internal( iterator i, iterator j )
47 : : {
48 [ + - ]: 11340 : EntitySequence* dead = *j;
49 [ + - ]: 11340 : sequenceSet.erase( j );
50 [ + - ][ + - ]: 11340 : ErrorCode rval = ( *i )->merge( *dead );
51 [ - + ]: 11340 : if( MB_SUCCESS != rval )
52 : : {
53 [ # # ]: 0 : sequenceSet.insert( dead );
54 : 0 : return rval;
55 : : }
56 : :
57 [ + + ][ + - ]: 11340 : if( lastReferenced == dead ) lastReferenced = *i;
58 [ + - ]: 11340 : delete dead;
59 : :
60 : : // If merging results in no unused portions of the SequenceData,
61 : : // remove it from the available list.
62 [ + - ][ + - ]: 11340 : if( ( *i )->using_entire_data() ) availableList.erase( ( *i )->data() );
[ + + ][ + - ]
[ + - ][ + - ]
63 : :
64 : 11340 : return MB_SUCCESS;
65 : : }
66 : :
67 : 2563776 : ErrorCode TypeSequenceManager::check_merge_next( iterator i )
68 : : {
69 : 2563776 : iterator j = i;
70 [ + - ]: 2563776 : ++j;
71 [ + - ][ + - ]: 2563776 : if( j == end() || ( *j )->data() != ( *i )->data() || ( *j )->start_handle() > ( *i )->end_handle() + 1 )
[ + + ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + + # # ]
72 : 2552546 : return MB_SUCCESS;
73 : :
74 [ + - ][ + - ]: 11230 : assert( ( *i )->end_handle() + 1 == ( *j )->start_handle() );
[ + - ][ + - ]
[ - + ]
75 [ + - ]: 2563776 : return merge_internal( i, j );
76 : : }
77 : :
78 : 174 : ErrorCode TypeSequenceManager::check_merge_prev( iterator i )
79 : : {
80 [ + - ][ + - ]: 174 : if( i == begin() ) return MB_SUCCESS;
[ + + ]
81 : :
82 : 158 : iterator j = i;
83 [ + - ]: 158 : --j;
84 [ + - ][ + - ]: 158 : if( ( *j )->data() != ( *i )->data() || ( *j )->end_handle() + 1 < ( *i )->start_handle() ) return MB_SUCCESS;
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + + ]
85 : :
86 [ + - ][ + - ]: 110 : assert( ( *j )->end_handle() + 1 == ( *i )->start_handle() );
[ + - ][ + - ]
[ - + ]
87 [ + - ]: 174 : return merge_internal( i, j );
88 : : }
89 : :
90 : 1644 : ErrorCode TypeSequenceManager::insert_sequence( EntitySequence* seq_ptr )
91 : : {
92 [ + - ][ + + ]: 1644 : if( !seq_ptr->data() ) return MB_FAILURE;
93 : :
94 [ + - ][ + - ]: 4929 : if( seq_ptr->data()->start_handle() > seq_ptr->start_handle() ||
[ + - ][ + - ]
[ - + ]
95 [ + - ][ + - ]: 3286 : seq_ptr->data()->end_handle() < seq_ptr->end_handle() || seq_ptr->end_handle() < seq_ptr->start_handle() )
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ]
96 : 0 : return MB_FAILURE;
97 : :
98 [ + - ][ + - ]: 1643 : iterator i = lower_bound( seq_ptr->start_handle() );
99 [ + - ][ + - ]: 1643 : if( i != end() )
[ + + ]
100 : : {
101 [ + - ][ + - ]: 17 : if( ( *i )->start_handle() <= seq_ptr->end_handle() ) return MB_ALREADY_ALLOCATED;
[ + - ][ + + ]
102 [ + - ][ + - ]: 15 : if( seq_ptr->data() != ( *i )->data() && ( *i )->data()->start_handle() <= seq_ptr->data()->end_handle() )
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + + ]
103 : 1 : return MB_ALREADY_ALLOCATED;
104 : : }
105 : :
106 [ + - ][ + - ]: 1640 : if( i != begin() )
[ + + ]
107 : : {
108 : 402 : iterator j = i;
109 [ + - ]: 402 : --j;
110 [ + - ][ + - ]: 402 : if( seq_ptr->data() != ( *j )->data() && ( *j )->data()->end_handle() >= seq_ptr->data()->start_handle() )
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + + ]
111 : 402 : return MB_ALREADY_ALLOCATED;
112 : : }
113 : :
114 [ + - ]: 1638 : i = sequenceSet.insert( i, seq_ptr );
115 : :
116 : : // Merge with previous sequence ?
117 [ + - ][ + - ]: 1638 : if( seq_ptr->start_handle() > seq_ptr->data()->start_handle() && i != begin() )
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ][ + + ]
[ + + # # ]
118 : : {
119 [ + - ][ - + ]: 140 : if( MB_SUCCESS != check_merge_prev( i ) )
120 : : {
121 [ # # ]: 0 : sequenceSet.erase( i );
122 : 0 : return MB_FAILURE;
123 : : }
124 : : }
125 : :
126 : : // Merge with next sequence ?
127 [ + - ][ + - ]: 1638 : if( ( *i )->end_handle() < ( *i )->data()->end_handle() )
[ + - ][ + - ]
[ + - ][ + + ]
128 : : {
129 [ + - ][ - + ]: 1047 : if( MB_SUCCESS != check_merge_next( i ) )
130 : : {
131 [ # # ]: 0 : sequenceSet.erase( i );
132 : 0 : return MB_FAILURE;
133 : : }
134 : : }
135 : :
136 : : // We merged adjacent sequences sharing a SequenceData, so
137 : : // we can safely assume that unless this EntitySequence is
138 : : // using the entire SequenceData, there are unused portions.
139 [ + - ][ + + ]: 1638 : if( !seq_ptr->using_entire_data() ) availableList.insert( seq_ptr->data() );
[ + - ][ + - ]
140 : :
141 : : // lastReferenced is only allowed to be NULL if there are
142 : : // no sequences (avoids unnecessary if's in fast path).
143 [ + + ]: 1638 : if( !lastReferenced ) lastReferenced = seq_ptr;
144 : :
145 : : // Each SequenceData has a pointer to the first EntitySequence
146 : : // referencing it. Update that pointer if the new sequence is
147 : : // the first one.
148 [ + - ][ + - ]: 1638 : if( ( *i )->start_handle() == ( *i )->data()->start_handle() || lower_bound( ( *i )->data()->start_handle() ) == i )
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + + ]
[ + + # # ]
149 [ + - ][ + - ]: 1608 : ( *i )->data()->seqManData.firstSequence = i;
150 : :
151 [ + - ][ - + ]: 1638 : assert( check_valid_data( seq_ptr ) );
152 : 1644 : return MB_SUCCESS;
153 : : }
154 : :
155 : 21 : ErrorCode TypeSequenceManager::replace_subsequence( EntitySequence* seq_ptr, const int* tag_sizes, int num_tag_sizes )
156 : : {
157 : : // Find the sequence of interest
158 [ + - ][ + - ]: 21 : iterator i = lower_bound( seq_ptr->start_handle() );
159 [ + - ][ + - ]: 21 : if( i == end() || ( *i )->data() == seq_ptr->data() ) return MB_FAILURE;
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ][ + - ]
[ - + ][ # # ]
160 : : // New sequence must be a subset of an existing one
161 [ + - ][ + - ]: 21 : if( seq_ptr->start_handle() < ( *i )->start_handle() || seq_ptr->end_handle() > ( *i )->end_handle() )
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + + ]
162 : 5 : return MB_FAILURE;
163 : : // New sequence's data must be new also, and cannot intersect
164 : : // any existing sequence (just require that the data range
165 : : // matches the sequence range for now)
166 [ + - ][ - + ]: 16 : if( !seq_ptr->using_entire_data() ) return MB_FAILURE;
167 : : // Copy tag data (move ownership of var-len data)
168 [ + - ][ + - ]: 16 : SequenceData* const dead_data = ( *i )->data();
169 [ + - ][ + - ]: 16 : dead_data->move_tag_data( seq_ptr->data(), tag_sizes, num_tag_sizes );
170 : :
171 : : // Split sequences sharing old data into two groups:
172 : : // p->i : first sequence to i
173 : : // i->n : i to one past last sequence
174 [ + - ]: 16 : iterator p, n = i;
175 [ + - ][ + - ]: 16 : p = ( *i )->data()->seqManData.firstSequence;
176 [ + - ][ + - ]: 20 : for( ++n; n != end() && ( *n )->data() == ( *i )->data(); ++n )
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ]
[ + + # # ]
177 : : ;
178 : :
179 : : // First subdivide EntitySequence as necessary
180 : : // Move i to be the first sequence past the insertion point
181 : : // such that the new order will be:
182 : : // [p,i-1] seq_ptr [i,n]
183 : : // where p == i if no previous sequence
184 : :
185 : : // Four possible cases:
186 : : // 0. All entities in sequence are in new sequence
187 : : // 1. Old entities in sequence before and after new sequence,
188 : : // requiring sequence to be split.
189 : : // 2. Old entities after new sequence
190 : : // 3. Old entities before new sequence
191 [ + - ][ + - ]: 16 : const bool some_before = ( ( *i )->start_handle() < seq_ptr->start_handle() );
[ + - ]
192 [ + - ][ + - ]: 16 : const bool some_after = ( ( *i )->end_handle() > seq_ptr->end_handle() );
[ + - ]
193 : : // Case 0
194 [ + + ][ + + ]: 16 : if( !( some_before || some_after ) )
195 : : {
196 : : // Remove dead sequence from internal lists
197 [ + - ]: 12 : EntitySequence* seq = *i;
198 : 12 : iterator dead = i;
199 [ + - ]: 12 : ++i;
200 [ + - ][ + - ]: 12 : if( p == dead ) p = i;
201 [ + - ]: 12 : sequenceSet.erase( dead );
202 : :
203 : : // Delete old sequence
204 [ + - ]: 12 : delete seq;
205 : : // Make sure lastReferenced isn't stale
206 [ + - ]: 12 : if( lastReferenced == seq ) lastReferenced = seq_ptr;
207 : : }
208 : : // Case 1
209 [ + + ][ + + ]: 4 : else if( some_before && some_after )
210 : : {
211 [ + - ][ + - ]: 1 : i = split_sequence( i, seq_ptr->start_handle() );
212 [ + - ][ + - ]: 1 : ( *i )->pop_front( seq_ptr->size() );
[ + - ]
213 : : }
214 : : // Case 2
215 [ + + ]: 3 : else if( some_after )
216 : : {
217 [ + - ][ + - ]: 1 : ( *i )->pop_front( seq_ptr->size() );
[ + - ]
218 : : }
219 : : // Case 3
220 : : else
221 : : { // some_before
222 [ + - ][ + - ]: 2 : ( *i )->pop_back( seq_ptr->size() );
[ + - ]
223 [ + - ]: 2 : ++i;
224 : : }
225 : :
226 : : // Now subdivide the underlying sequence data as necessary
227 [ + - ]: 16 : availableList.erase( dead_data );
228 [ + - ][ + + ]: 16 : if( p != i )
229 : : {
230 : 3 : iterator last = i;
231 [ + - ]: 3 : --last;
232 [ + - ][ + - ]: 3 : SequenceData* new_data = ( *p )->create_data_subset( ( *p )->start_handle(), ( *last )->end_handle() );
[ + - ][ + - ]
[ + - ][ + - ]
233 : 3 : new_data->seqManData.firstSequence = p;
234 : :
235 [ + - ][ + - ]: 9 : for( ; p != i; ++p )
[ + + ]
236 [ + - ][ + - ]: 6 : ( *p )->data( new_data );
237 : : // Copy tag data (move ownership of var-len data)
238 [ + - ]: 3 : dead_data->move_tag_data( new_data, tag_sizes, num_tag_sizes );
239 [ + - ][ + - ]: 3 : if( !( *new_data->seqManData.firstSequence )->using_entire_data() ) availableList.insert( new_data );
[ + + ][ + - ]
240 : : }
241 [ + - ][ + + ]: 16 : if( i != n )
242 : : {
243 : 3 : iterator last = n;
244 [ + - ]: 3 : --last;
245 [ + - ][ + - ]: 3 : SequenceData* new_data = ( *i )->create_data_subset( ( *i )->start_handle(), ( *last )->end_handle() );
[ + - ][ + - ]
[ + - ][ + - ]
246 : 3 : new_data->seqManData.firstSequence = i;
247 [ + - ][ + - ]: 9 : for( ; i != n; ++i )
[ + + ]
248 [ + - ][ + - ]: 6 : ( *i )->data( new_data );
249 : : // Copy tag data (move ownership of var-len data)
250 [ + - ]: 3 : dead_data->move_tag_data( new_data, tag_sizes, num_tag_sizes );
251 [ + - ][ + - ]: 3 : if( !( *new_data->seqManData.firstSequence )->using_entire_data() ) availableList.insert( new_data );
[ + + ][ + - ]
252 : : }
253 [ + - ]: 16 : delete dead_data;
254 : :
255 : : // Put new sequence in lists
256 [ + - ]: 21 : return insert_sequence( seq_ptr );
257 : : }
258 : :
259 : 11 : TypeSequenceManager::iterator TypeSequenceManager::erase( iterator i )
260 : : {
261 [ + - ]: 11 : EntitySequence* seq = *i;
262 [ + - ]: 11 : SequenceData* data = seq->data();
263 [ + - ]: 11 : iterator j;
264 : :
265 : : // Check if we need to delete the referenced SequenceData also
266 : : bool delete_data;
267 [ + - ][ + + ]: 11 : if( seq->using_entire_data() ) // Only sequence
268 : 1 : delete_data = true;
269 [ + - ][ + + ]: 10 : else if( data->seqManData.firstSequence != i )
270 : : { // Earlier sequence?
271 : 1 : delete_data = false;
272 [ + - ]: 1 : availableList.insert( data );
273 : : }
274 : : else
275 : : { // Later sequence ?
276 : 9 : j = i;
277 [ + - ]: 9 : ++j;
278 [ + - ][ + - ]: 9 : delete_data = ( j == end() || ( *j )->data() != data );
[ + + ][ + - ]
[ + - ][ - + ]
[ + - ][ # # ]
279 [ + + ]: 9 : if( delete_data )
280 [ + - ]: 7 : availableList.erase( data );
281 : : else
282 : : {
283 [ + - ]: 2 : availableList.insert( data );
284 : 2 : data->seqManData.firstSequence = j;
285 : : }
286 : : }
287 : :
288 : : // Remove sequence, updating i to be next sequence
289 [ + - ]: 11 : j = i++;
290 [ + - ]: 11 : sequenceSet.erase( j );
291 : :
292 : : // Make sure lastReferenced isn't stale. It can only be NULL if
293 : : // no sequences.
294 [ + + ][ + + ]: 11 : if( lastReferenced == seq ) lastReferenced = sequenceSet.empty() ? 0 : *sequenceSet.begin();
[ + - ][ + + ]
[ # # ]
295 : :
296 : : // Always delete sequence before the SequenceData it references.
297 [ + - ][ + - ]: 11 : assert( 0 == find( seq->start_handle() ) );
[ - + ]
298 [ + - ]: 11 : delete seq;
299 [ + + ]: 11 : if( delete_data )
300 [ + - ]: 8 : delete data;
301 : : else
302 : : {
303 [ + - ][ + - ]: 3 : assert( check_valid_data( *data->seqManData.firstSequence ) );
[ - + ]
304 [ - + ]: 3 : assert( lastReferenced != seq );
305 : : }
306 : 11 : return i;
307 : : }
308 : :
309 : 6855 : ErrorCode TypeSequenceManager::remove_sequence( const EntitySequence* seq_ptr, bool& unreferenced_data )
310 : : {
311 : : // Remove sequence from set
312 [ + - ][ + - ]: 6855 : iterator i = lower_bound( seq_ptr->start_handle() );
313 [ + - ][ + - ]: 6855 : if( i == end() || *i != seq_ptr ) return MB_ENTITY_NOT_FOUND;
[ + - ][ + - ]
[ + + ][ + - ]
[ + + ][ # # ]
314 [ + - ]: 6854 : sequenceSet.erase( i );
315 : :
316 : : // Check if this is the only sequence referencing its data
317 [ + - ][ - + ]: 6854 : if( seq_ptr->using_entire_data() )
318 : 0 : unreferenced_data = true;
319 : : else
320 : : {
321 [ + - ][ + - ]: 6854 : i = lower_bound( seq_ptr->data()->start_handle() );
[ + - ]
322 [ + - ][ + - ]: 6854 : unreferenced_data = i == end() || ( *i )->data() != seq_ptr->data();
[ + + ][ + - ]
[ + - ][ + - ]
[ - + ][ + - ]
[ # # ]
323 [ + + ]: 6854 : if( unreferenced_data )
324 [ + - ][ + - ]: 46 : availableList.erase( seq_ptr->data() );
325 : : else
326 [ + - ]: 6808 : seq_ptr->data()->seqManData.firstSequence = i; // Might be 'i' already
327 : : }
328 : :
329 [ + + ][ + + ]: 6854 : if( lastReferenced == seq_ptr ) lastReferenced = sequenceSet.empty() ? 0 : *sequenceSet.begin();
[ + - ][ + + ]
[ # # ]
330 : :
331 : 6855 : return MB_SUCCESS;
332 : : }
333 : :
334 : 2563662 : TypeSequenceManager::iterator TypeSequenceManager::find_free_handle( EntityHandle min_start_handle,
335 : : EntityHandle max_end_handle, bool& append_out,
336 : : int values_per_ent )
337 : : {
338 [ + - ][ + - ]: 2574922 : for( data_iterator i = availableList.begin(); i != availableList.end(); ++i )
[ + + ]
339 : : {
340 [ + - ][ + - ]: 2574028 : if( ( *( *i )->seqManData.firstSequence )->values_per_entity() != values_per_ent ) continue;
[ + - ][ + + ]
341 : :
342 [ + - ][ + - ]: 2562769 : if( ( *i )->start_handle() > max_end_handle || ( *i )->end_handle() < min_start_handle ) continue;
[ + - ][ + - ]
[ + - ][ - + ]
[ - + ]
343 : :
344 [ + - ][ + - ]: 7688319 : for( iterator j = ( *i )->seqManData.firstSequence;
[ + + ]
345 [ + - ][ + - ]: 5125546 : j != end() && ( *j )->start_handle() <= ( max_end_handle + 1 ) && ( *j )->data() == *i; ++j )
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ][ # # ]
346 : : {
347 [ + - ][ + - ]: 2562772 : if( ( *j )->end_handle() + 1 < min_start_handle ) continue;
[ + + ]
348 [ + - ][ + - ]: 2562768 : if( ( *j )->start_handle() > ( *i )->start_handle() && ( *j )->start_handle() > min_start_handle )
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + + ]
[ + + ]
349 : : {
350 : 37 : append_out = false;
351 : 2562768 : return j;
352 : : }
353 [ + - ][ + - ]: 2562731 : if( ( *j )->end_handle() < ( *i )->end_handle() && ( *j )->end_handle() < max_end_handle )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
354 : : {
355 : 2562731 : append_out = true;
356 : 2562731 : return j;
357 : : }
358 : : }
359 : : }
360 : :
361 : 2563662 : return end();
362 : : }
363 : :
364 : 310 : bool TypeSequenceManager::is_free_sequence( EntityHandle start, EntityID num_entities, SequenceData*& data_out,
365 : : int values_per_ent )
366 : : {
367 : 310 : data_out = 0;
368 [ + - ][ + + ]: 310 : if( empty() ) return true;
369 : :
370 [ + - ]: 87 : const_iterator i = lower_bound( start );
371 [ + - ][ + - ]: 87 : if( i == end() )
[ + + ]
372 : : {
373 [ + - ]: 40 : --i; // Safe because already tested empty()
374 : : // If we don't overlap the last data object...
375 [ + - ][ + - ]: 40 : if( ( *i )->data()->end_handle() < start ) return true;
[ + - ][ + + ]
376 [ + - ][ + - ]: 2 : data_out = ( *i )->data();
377 [ + - ][ + - ]: 2 : if( ( *i )->values_per_entity() != values_per_ent ) return false;
[ - + ]
378 : : // If we overlap a data object, we must be entirely inside of it
379 [ + - ][ + - ]: 2 : return start + num_entities - 1 <= ( *i )->data()->end_handle();
[ + - ]
380 : : }
381 : :
382 : : #ifndef NDEBUG
383 [ + - ][ + - ]: 47 : if( i != begin() )
[ + + ]
384 : : {
385 : 5 : const_iterator j = i;
386 [ + - ]: 5 : --j;
387 [ + - ][ + - ]: 5 : assert( ( *j )->end_handle() < start );
[ - + ]
388 : : }
389 : : #endif
390 : :
391 : : // Check if we fit in the block of free handles
392 [ + - ][ + - ]: 47 : if( start + num_entities > ( *i )->start_handle() ) // start + num + 1 >= i->start
[ + + ]
393 : 44 : return false;
394 : :
395 : : // Check if we overlap the data for the next sequence
396 [ + - ][ + - ]: 3 : if( start + num_entities > ( *i )->data()->start_handle() )
[ + - ][ + - ]
397 : : {
398 [ + - ][ + - ]: 3 : data_out = ( *i )->data();
399 [ + - ][ + - ]: 3 : if( ( *i )->values_per_entity() != values_per_ent ) return false;
[ - + ]
400 : : // If overlap, must be entirely contained
401 [ + - ][ + - ]: 3 : return start >= data_out->start_handle() && start + num_entities - 1 <= data_out->end_handle();
[ + - ][ + - ]
402 : : }
403 : :
404 : : // Check if we overlap the data for the previous sequence
405 [ # # ][ # # ]: 0 : if( i != begin() )
[ # # ]
406 : : {
407 [ # # ]: 0 : --i;
408 [ # # ][ # # ]: 0 : if( ( *i )->data()->end_handle() >= start )
[ # # ][ # # ]
409 : : {
410 [ # # ][ # # ]: 0 : data_out = ( *i )->data();
411 [ # # ][ # # ]: 0 : if( ( *i )->values_per_entity() != values_per_ent ) return false;
[ # # ]
412 [ # # ][ # # ]: 0 : return start + num_entities - 1 <= ( *i )->data()->end_handle();
[ # # ]
413 : : }
414 : : }
415 : :
416 : : // Unused handle block that overlaps no SequenceData
417 : 310 : return true;
418 : : }
419 : :
420 : 0 : EntityHandle TypeSequenceManager::find_free_block( EntityID num_entities, EntityHandle min_start_handle,
421 : : EntityHandle max_end_handle )
422 : : {
423 [ # # ]: 0 : const_iterator i = lower_bound( min_start_handle );
424 [ # # ][ # # ]: 0 : if( i == end() ) return min_start_handle;
[ # # ]
425 : :
426 [ # # ][ # # ]: 0 : if( ( *i )->start_handle() < min_start_handle + num_entities ) return min_start_handle;
[ # # ]
427 : :
428 [ # # ][ # # ]: 0 : EntityHandle prev_end = ( *i )->end_handle();
429 [ # # ]: 0 : ++i;
430 [ # # ][ # # ]: 0 : for( ; i != end(); prev_end = ( *i )->end_handle(), ++i )
[ # # ][ # # ]
[ # # ][ # # ]
431 : : {
432 [ # # ][ # # ]: 0 : EntityID len = ( *i )->start_handle() - prev_end - 1;
433 [ # # ]: 0 : if( len >= num_entities ) break;
434 : : }
435 : :
436 [ # # ]: 0 : if( prev_end + num_entities > max_end_handle )
437 : 0 : return 0;
438 : : else
439 : 0 : return prev_end + 1;
440 : : }
441 : :
442 : : struct range_data
443 : : {
444 : : EntityID num_entities;
445 : : EntityHandle min_start_handle, max_end_handle;
446 : : EntityHandle first, last;
447 : : };
448 : :
449 : 1602 : static bool check_range( const range_data& d, bool prefer_end, EntityHandle& result )
450 : : {
451 : 1602 : EntityHandle first = std::max( d.min_start_handle, d.first );
452 : 1602 : EntityHandle last = std::min( d.max_end_handle, d.last );
453 [ + + ]: 1602 : if( last < first + d.num_entities - 1 )
454 : : {
455 : 1275 : result = 0;
456 : 1275 : return false;
457 : : }
458 : :
459 [ + + ]: 327 : result = prefer_end ? last + 1 - d.num_entities : first;
460 : 327 : return true;
461 : : }
462 : :
463 : 1319 : EntityHandle TypeSequenceManager::find_free_sequence( EntityID num_entities, EntityHandle min_start_handle,
464 : : EntityHandle max_end_handle, SequenceData*& data_out,
465 : : EntityID& data_size, int num_verts )
466 : : {
467 [ - + ]: 1319 : if( max_end_handle < min_start_handle + num_entities - 1 ) return 0;
468 : :
469 : : EntityHandle result;
470 [ + - ][ + - ]: 1319 : iterator p, i = lower_bound( min_start_handle );
471 : 1319 : range_data d = { num_entities, min_start_handle, max_end_handle, 0, 0 };
472 : :
473 [ + - ][ + - ]: 1319 : if( i == end() )
[ + + ]
474 : : {
475 : 990 : data_out = 0;
476 : 990 : return min_start_handle;
477 : : }
478 [ + - ][ + - ]: 329 : else if( i == begin() )
[ + + ]
479 : : {
480 [ + - ][ + - ]: 328 : if( ( *i )->values_per_entity() == num_verts )
[ + + ]
481 : : {
482 [ + - ][ + - ]: 284 : d.first = ( *i )->data()->start_handle();
[ + - ]
483 [ + - ][ + - ]: 284 : d.last = ( *i )->start_handle() - 1;
484 [ + - ][ + + ]: 284 : if( check_range( d, true, result ) )
485 : : {
486 [ + - ][ + - ]: 1 : data_out = ( *i )->data();
487 : 1 : return result;
488 : : }
489 : : }
490 : 327 : d.first = min_start_handle;
491 [ + - ][ + - ]: 327 : d.last = ( *i )->data()->start_handle() - 1;
[ + - ]
492 [ + - ][ + + ]: 327 : if( check_range( d, true, result ) )
493 : : {
494 : 3 : data_out = 0;
495 : : // This will back up against the end of the seq data, so
496 : : // size the data that way
497 : 3 : data_size = num_entities;
498 : 3 : return result;
499 : : }
500 [ + - ]: 324 : p = i++;
501 : : }
502 : : else
503 : : {
504 : 1 : p = i;
505 [ + - ]: 1 : --p;
506 : : }
507 : :
508 [ + - ][ + - ]: 580 : for( ; i != end() && ( *i )->start_handle() < max_end_handle; p = i++ )
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + + # # ]
509 : : {
510 [ + - ][ + - ]: 256 : if( ( *p )->data() == ( *i )->data() )
[ + - ][ + - ]
[ + + ]
511 : : {
512 [ + - ][ + - ]: 7 : if( ( *p )->values_per_entity() == num_verts )
[ + - ]
513 : : {
514 [ + - ][ + - ]: 7 : d.first = ( *p )->end_handle() + 1;
515 [ + - ][ + - ]: 7 : d.last = ( *i )->start_handle() - 1;
516 [ + - ][ + + ]: 7 : if( check_range( d, false, result ) )
517 : : {
518 [ + - ][ + - ]: 1 : data_out = ( *p )->data();
519 : 1 : return result;
520 : : }
521 : : }
522 : : }
523 : : else
524 : : {
525 [ + - ][ + - ]: 249 : if( ( *p )->values_per_entity() == num_verts )
[ + + ]
526 : : {
527 [ + - ][ + - ]: 123 : d.first = ( *p )->end_handle() + 1;
528 [ + - ][ + - ]: 123 : d.last = ( *p )->data()->end_handle();
[ + - ]
529 [ + - ][ - + ]: 123 : if( check_range( d, false, result ) )
530 : : {
531 [ # # ][ # # ]: 0 : data_out = ( *p )->data();
532 : 0 : return result;
533 : : }
534 : : }
535 [ + - ][ + - ]: 249 : if( ( *i )->values_per_entity() == num_verts )
[ + + ]
536 : : {
537 [ + - ][ + - ]: 121 : d.first = ( *i )->data()->start_handle();
[ + - ]
538 [ + - ][ + - ]: 121 : d.last = ( *i )->start_handle() - 1;
539 [ + - ][ - + ]: 121 : if( check_range( d, true, result ) )
540 : : {
541 [ # # ][ # # ]: 0 : data_out = ( *i )->data();
542 : 0 : return result;
543 : : }
544 : : }
545 [ + - ][ + - ]: 249 : d.first = ( *p )->data()->end_handle() + 1;
[ + - ]
546 [ + - ][ + - ]: 249 : d.last = ( *i )->data()->start_handle() - 1;
[ + - ]
547 [ + - ][ - + ]: 249 : if( check_range( d, false, result ) )
548 : : {
549 : 0 : data_out = 0;
550 : 0 : data_size = d.last - d.first + 1;
551 : 0 : return result;
552 : : }
553 : : }
554 : : }
555 : :
556 [ + - ][ + - ]: 324 : if( ( *p )->values_per_entity() == num_verts )
[ + + ]
557 : : {
558 [ + - ][ + - ]: 278 : d.first = ( *p )->end_handle() + 1;
559 [ + - ][ + - ]: 278 : d.last = ( *p )->data()->end_handle();
[ + - ]
560 [ + - ][ + + ]: 278 : if( check_range( d, false, result ) )
561 : : {
562 [ + - ][ + - ]: 111 : data_out = ( *p )->data();
563 : 111 : return result;
564 : : }
565 : : }
566 : :
567 [ + - ][ + - ]: 213 : d.first = ( *p )->data()->end_handle() + 1;
[ + - ]
568 : 213 : d.last = max_end_handle;
569 [ + - ][ + + ]: 213 : if( check_range( d, false, result ) )
570 : : {
571 : 211 : data_out = 0;
572 : 211 : return result;
573 : : }
574 : :
575 : 2 : data_out = 0;
576 : 1319 : return 0;
577 : : }
578 : :
579 : 0 : EntityHandle TypeSequenceManager::last_free_handle( EntityHandle after_this ) const
580 : : {
581 : : int junk;
582 [ # # ]: 0 : const_iterator it = lower_bound( after_this );
583 [ # # ][ # # ]: 0 : if( it == end() )
[ # # ]
584 [ # # ][ # # ]: 0 : return CREATE_HANDLE( TYPE_FROM_HANDLE( after_this ), MB_END_ID, junk );
585 [ # # ][ # # ]: 0 : else if( ( *it )->start_handle() > after_this )
[ # # ]
586 : : {
587 : : // Need to check against the sequence data first
588 [ # # ][ # # ]: 0 : EntityHandle rhandle = ( *it )->data()->start_handle();
[ # # ]
589 : 0 : return rhandle - 1;
590 : : }
591 : : else
592 : 0 : return 0;
593 : : }
594 : :
595 : 25175 : ErrorCode TypeSequenceManager::check_valid_handles( Error* /* error_handler */, EntityHandle first,
596 : : EntityHandle last ) const
597 : : {
598 [ + - ]: 25175 : const_iterator i = lower_bound( first );
599 [ + - ][ + - ]: 25175 : if( i == end() || ( *i )->start_handle() > first )
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ]
[ + + # # ]
600 : : {
601 : : #if 0
602 : : // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call
603 : : // MB_SET_ERR on it
604 : : fprintf(
605 : : stderr,
606 : : "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)first
607 : : );
608 : : #endif
609 : 7 : return MB_ENTITY_NOT_FOUND;
610 : : }
611 : :
612 [ + - ][ + - ]: 25182 : while( ( *i )->end_handle() < last )
[ + + ]
613 : : {
614 [ + - ][ + - ]: 15 : EntityHandle prev_end = ( *i )->end_handle();
615 [ + - ]: 15 : ++i;
616 [ + - ][ + - ]: 15 : if( i == end() || prev_end + 1 != ( *i )->start_handle() ) return MB_ENTITY_NOT_FOUND;
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + + ]
[ # # ]
617 : : }
618 : :
619 : 25175 : return MB_SUCCESS;
620 : : }
621 : :
622 : 30113 : ErrorCode TypeSequenceManager::erase( Error* /* error_handler */, EntityHandle h )
623 : : {
624 : 30113 : EntitySequence* seq = find( h );
625 [ - + ]: 30113 : if( !seq )
626 : : {
627 : : #if 0
628 : : // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call
629 : : // MB_SET_ERR on it
630 : : fprintf(
631 : : stderr,
632 : : "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)h
633 : : );
634 : : #endif
635 : 0 : return MB_ENTITY_NOT_FOUND;
636 : : }
637 : :
638 [ + + ]: 30113 : if( seq->start_handle() == h )
639 : : {
640 [ + - ][ + + ]: 19145 : if( seq->end_handle() != h )
641 : : {
642 [ + - ][ + + ]: 12294 : if( seq->using_entire_data() ) availableList.insert( seq->data() );
[ + - ][ + - ]
643 [ + - ]: 12294 : seq->pop_front( 1 );
644 : 12294 : return MB_SUCCESS;
645 : : }
646 [ + - ]: 6851 : SequenceData* data = seq->data();
647 : : bool delete_data;
648 [ + - ]: 6851 : ErrorCode rval = remove_sequence( seq, delete_data );
649 [ - + ]: 6851 : if( MB_SUCCESS != rval ) return rval;
650 [ + - ]: 6851 : delete seq;
651 [ + + ][ + - ]: 6851 : if( delete_data ) delete data;
652 : : }
653 [ + + ]: 10968 : else if( seq->end_handle() == h )
654 : : {
655 [ - + ][ # # ]: 3910 : if( seq->using_entire_data() ) availableList.insert( seq->data() );
656 : 3910 : seq->pop_back( 1 );
657 : : }
658 : : else
659 : : {
660 [ + - ]: 7058 : iterator i = lower_bound( h );
661 [ + - ][ + - ]: 7058 : if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
[ + + ][ + - ]
[ + - ][ + - ]
662 [ + - ]: 7058 : i = split_sequence( i, h );
663 [ + - ]: 7058 : seq = *i;
664 [ + - ][ - + ]: 7058 : assert( seq->start_handle() == h );
665 [ + - ]: 7058 : seq->pop_front( 1 );
666 : : }
667 : :
668 : 30113 : return MB_SUCCESS;
669 : : }
670 : :
671 : 12282 : ErrorCode TypeSequenceManager::erase( Error* /* error */, EntityHandle first, EntityHandle last )
672 : : {
673 : : // First check that all entities in range are valid
674 : :
675 [ + - ]: 12282 : ErrorCode rval = check_valid_handles( NULL, first, last );
676 [ + + ]: 12282 : if( MB_SUCCESS != rval ) return rval;
677 : :
678 : : // Now remove entities
679 : :
680 : : // Get first sequence intersecting range
681 [ + - ]: 12280 : iterator i = lower_bound( first );
682 [ + - ][ + - ]: 12280 : if( i == end() ) // Shouldn't be possible given check_valid_handles call above.
[ - + ]
683 : 0 : return MB_ENTITY_NOT_FOUND;
684 : :
685 : : // If range is entirely in interior of sequence, need to split sequence.
686 [ + - ][ + - ]: 12280 : if( ( *i )->start_handle() < first && ( *i )->end_handle() > last )
[ + + ][ + - ]
[ + - ][ + + ]
[ + + ]
687 : : {
688 [ + - ][ + - ]: 12225 : if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
[ + + ][ + - ]
[ + - ][ + - ]
689 [ + - ]: 12225 : i = split_sequence( i, first );
690 [ + - ][ + - ]: 12225 : ( *i )->pop_front( last - first + 1 );
691 [ + - ][ + - ]: 12225 : assert( check_valid_data( *i ) );
[ - + ]
692 : 12225 : return MB_SUCCESS;
693 : : }
694 : :
695 : : // If range doesn't entirely contain first sequence, remove some
696 : : // handles from the end of the sequence and advance to the next
697 : : // sequence.
698 [ + - ][ + - ]: 55 : if( ( *i )->start_handle() < first )
[ + + ]
699 : : {
700 [ + - ][ + - ]: 23 : if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
[ + + ][ + - ]
[ + - ][ + - ]
701 [ + - ][ + - ]: 23 : ( *i )->pop_back( ( *i )->end_handle() - first + 1 );
[ + - ][ + - ]
702 [ + - ]: 23 : ++i;
703 : : }
704 : :
705 : : // Destroy all sequences contained entirely within the range
706 [ + - ][ + - ]: 66 : while( i != end() && ( *i )->end_handle() <= last )
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ]
[ + + # # ]
707 [ + - ]: 11 : i = erase( i );
708 : :
709 : : // If necessary, remove entities from the beginning of the
710 : : // last sequence.
711 [ + - ][ + - ]: 55 : if( i != end() && ( *i )->start_handle() <= last )
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ]
[ + + # # ]
712 : : {
713 [ + - ][ + - ]: 28 : if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
[ + + ][ + - ]
[ + - ][ + - ]
714 [ + - ][ + - ]: 28 : ( *i )->pop_front( last - ( *i )->start_handle() + 1 );
[ + - ][ + - ]
715 [ + - ][ + - ]: 28 : assert( check_valid_data( *i ) );
[ - + ]
716 : : }
717 : :
718 : 12282 : return MB_SUCCESS;
719 : : }
720 : :
721 : 19284 : TypeSequenceManager::iterator TypeSequenceManager::split_sequence( iterator i, EntityHandle h )
722 : : {
723 [ + - ][ + - ]: 19284 : EntitySequence* seq = ( *i )->split( h );
724 [ - + ][ # # ]: 19284 : if( !seq ) return end();
725 : :
726 [ + - ]: 19284 : i = sequenceSet.insert( i, seq );
727 [ + - ][ + - ]: 19284 : assert( check_valid_data( *i ) );
[ - + ]
728 : :
729 : 19284 : return i;
730 : : }
731 : :
732 : 0 : ErrorCode TypeSequenceManager::is_free_handle( EntityHandle handle, iterator& seq_iter_out, SequenceData*& data_ptr_out,
733 : : EntityHandle& block_start, EntityHandle& block_end, int values_per_ent )
734 : : {
735 : : int junk;
736 [ # # ][ # # ]: 0 : block_start = CREATE_HANDLE( TYPE_FROM_HANDLE( handle ), MB_START_ID, junk );
737 [ # # ][ # # ]: 0 : block_end = CREATE_HANDLE( TYPE_FROM_HANDLE( handle ), MB_END_ID, junk );
738 : :
739 [ # # ]: 0 : iterator i = lower_bound( handle );
740 [ # # ][ # # ]: 0 : if( i != end() )
[ # # ]
741 : : {
742 [ # # ][ # # ]: 0 : block_end = ( *i )->start_handle() - 1;
743 : :
744 : : // If sequence contains handle, then already allocated
745 [ # # ][ # # ]: 0 : if( ( *i )->start_handle() <= handle ) return MB_ALREADY_ALLOCATED;
[ # # ]
746 : :
747 : : // Handle is not within an existing sequence, but is
748 : : // within an existing SequenceData...
749 [ # # ][ # # ]: 0 : if( ( *i )->data()->start_handle() <= handle )
[ # # ][ # # ]
750 : : {
751 : : // If values_per_entity don't match, can't put new entity
752 : : // in existing SequenceData
753 [ # # ][ # # ]: 0 : if( ( *i )->values_per_entity() != values_per_ent ) return MB_ALREADY_ALLOCATED;
[ # # ]
754 : :
755 [ # # ][ # # ]: 0 : data_ptr_out = ( *i )->data();
756 [ # # ]: 0 : if( block_end == handle )
757 : : {
758 : : // Prepend to existing sequence
759 : 0 : seq_iter_out = i;
760 : 0 : block_start = handle;
761 : : }
762 : : else
763 : : {
764 : : // Add new sequence to existing SequenceData
765 [ # # ]: 0 : seq_iter_out = end();
766 [ # # ][ # # ]: 0 : if( i == begin() || ( *--i )->data() != data_ptr_out )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
767 [ # # ]: 0 : block_start = data_ptr_out->start_handle();
768 : : else
769 [ # # ][ # # ]: 0 : block_start = ( *i )->end_handle() + 1;
770 : : }
771 : 0 : return MB_SUCCESS;
772 : : }
773 : : }
774 : :
775 [ # # ][ # # ]: 0 : if( i != begin() )
[ # # ]
776 : : {
777 [ # # ]: 0 : --i;
778 [ # # ][ # # ]: 0 : block_start = ( *i )->end_handle() + 1;
779 : :
780 : : // Handle is within previous sequence data...
781 [ # # ][ # # ]: 0 : if( ( *i )->data()->end_handle() >= handle )
[ # # ][ # # ]
782 : : {
783 : : // If values_per_entity don't match, can't put new entity
784 : : // in existing SequenceData
785 [ # # ][ # # ]: 0 : if( ( *i )->values_per_entity() != values_per_ent ) return MB_ALREADY_ALLOCATED;
[ # # ]
786 : :
787 [ # # ][ # # ]: 0 : data_ptr_out = ( *i )->data();
788 [ # # ]: 0 : if( block_start == handle )
789 : : {
790 : : // Append to existing sequence
791 : 0 : seq_iter_out = i;
792 : 0 : block_end = handle;
793 : : }
794 : : else
795 : : {
796 : : // Add new sequence to existing SequenceData
797 [ # # ]: 0 : seq_iter_out = end();
798 [ # # ][ # # ]: 0 : if( ++i == end() || ( *i )->data() != data_ptr_out )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
799 [ # # ]: 0 : block_end = data_ptr_out->end_handle();
800 : : else
801 [ # # ][ # # ]: 0 : block_end = ( *i )->start_handle() - 1;
802 : : }
803 : 0 : return MB_SUCCESS;
804 : : }
805 : : }
806 : :
807 [ # # ]: 0 : seq_iter_out = end();
808 : 0 : data_ptr_out = 0;
809 : :
810 : 0 : return MB_SUCCESS;
811 : : }
812 : :
813 : 2562729 : ErrorCode TypeSequenceManager::notify_appended( iterator seq )
814 : : {
815 : 2562729 : ErrorCode rval = check_merge_next( seq );
816 [ + + ][ + - ]: 2562729 : if( ( *seq )->using_entire_data() ) availableList.erase( ( *seq )->data() );
817 : :
818 : 2562729 : return rval;
819 : : }
820 : :
821 : 34 : ErrorCode TypeSequenceManager::notify_prepended( iterator seq )
822 : : {
823 : 34 : ErrorCode rval = check_merge_prev( seq );
824 [ - + ][ # # ]: 34 : if( ( *seq )->using_entire_data() ) availableList.erase( ( *seq )->data() );
825 : :
826 : 34 : return rval;
827 : : }
828 : :
829 : 48 : void TypeSequenceManager::get_memory_use( unsigned long long& entity_storage, unsigned long long& total_storage ) const
830 : : {
831 : 48 : entity_storage = total_storage = 0;
832 [ + - ][ + + ]: 54 : if( empty() ) return;
833 : :
834 [ + - ][ + - ]: 6 : EntityType mytype = TYPE_FROM_HANDLE( lastReferenced->start_handle() );
835 : : int junk;
836 : 6 : get_memory_use( CREATE_HANDLE( mytype, MB_START_ID, junk ), CREATE_HANDLE( mytype, MB_END_ID, junk ),
837 [ + - ][ + - ]: 6 : entity_storage, total_storage );
[ + - ]
838 : : }
839 : :
840 : 10 : void TypeSequenceManager::append_memory_use( EntityHandle first, EntityHandle last, const SequenceData* data,
841 : : unsigned long long& entity_storage,
842 : : unsigned long long& total_storage ) const
843 : : {
844 [ + - ]: 10 : const unsigned long allocated_count = data->size();
845 : :
846 : : unsigned long bytes_per_ent, seq_size;
847 : 10 : const_iterator i = data->seqManData.firstSequence;
848 [ + - ][ + - ]: 10 : ( *i )->get_const_memory_use( bytes_per_ent, seq_size );
849 : :
850 : 10 : unsigned long other_ent_mem = 0;
851 : 10 : unsigned long occupied_count = 0, entity_count = 0, sequence_count = 0;
852 [ + - ][ + - ]: 20 : for( ; i != end() && ( *i )->data() == data; ++i )
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + + # # ]
853 : : {
854 [ + - ][ + - ]: 10 : occupied_count += ( *i )->size();
855 : 10 : ++sequence_count;
856 : :
857 [ + - ][ + - ]: 10 : EntityHandle start = std::max( first, ( *i )->start_handle() );
[ + - ]
858 [ + - ][ + - ]: 10 : EntityHandle stop = std::min( last, ( *i )->end_handle() );
[ + - ]
859 [ - + ]: 10 : if( stop < start ) continue;
860 : :
861 : 10 : entity_count += stop - start + 1;
862 [ + - ][ + - ]: 10 : other_ent_mem += ( *i )->get_per_entity_memory_use( start, stop );
863 : : }
864 : :
865 : 10 : unsigned long sum = sequence_count * seq_size + allocated_count * bytes_per_ent;
866 : :
867 : : // Watch for overflow
868 [ + - ][ + - ]: 10 : assert( entity_count > 0 && occupied_count > 0 && allocated_count > 0 );
[ - + ]
869 [ - + ]: 10 : if( std::numeric_limits< unsigned long >::max() / entity_count <= sum )
870 : : {
871 : 0 : total_storage += sum * ( entity_count / occupied_count ) + other_ent_mem;
872 : 0 : entity_storage += sum * ( entity_count / allocated_count ) + other_ent_mem;
873 : : }
874 : : else
875 : : {
876 : 10 : total_storage += sum * entity_count / occupied_count + other_ent_mem;
877 : 10 : entity_storage += sum * entity_count / allocated_count + other_ent_mem;
878 : : }
879 : 10 : }
880 : :
881 : 10 : void TypeSequenceManager::get_memory_use( EntityHandle first, EntityHandle last, unsigned long long& entity_storage,
882 : : unsigned long long& total_storage ) const
883 : : {
884 : 10 : entity_storage = total_storage = 0;
885 : :
886 [ + + ]: 20 : while( first <= last )
887 : : {
888 [ + - ]: 16 : const_iterator i = lower_bound( first );
889 [ + - ][ + - ]: 20 : if( i == end() ) return;
[ + + ]
890 : :
891 [ + - ][ + - ]: 10 : SequenceData* data = ( *i )->data();
892 [ + - ][ + - ]: 10 : if( first < data->end_handle() ) { append_memory_use( first, last, data, entity_storage, total_storage ); }
[ + - ]
893 [ + - ]: 10 : first = data->end_handle() + 1;
894 : : }
895 : : }
896 : :
897 : 0 : EntityID TypeSequenceManager::get_occupied_size( const SequenceData* data ) const
898 : : {
899 : 0 : EntityID result = 0;
900 [ # # ][ # # ]: 0 : for( const_iterator i = data->seqManData.firstSequence; i != end() && ( *i )->data() == data; ++i )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
901 [ # # ][ # # ]: 0 : result += ( *i )->size();
902 : :
903 : 0 : return result;
904 : : }
905 : :
906 : : #ifndef NDEBUG
907 : 33178 : bool TypeSequenceManager::check_valid_data( const EntitySequence* seq ) const
908 : : {
909 : : // Caller passed a sequence that should be contained, so cannot be empty
910 [ + - ][ - + ]: 33178 : if( empty() ) return false;
911 : :
912 : : // Make sure lastReferenced points to something
913 [ - + ]: 33178 : if( !lastReferenced ) return false;
914 : :
915 [ + - ]: 33178 : const_iterator seqi = sequenceSet.lower_bound( lastReferenced );
916 [ + - ][ + - ]: 33178 : if( seqi == sequenceSet.end() || *seqi != lastReferenced ) return false;
[ + - ][ - + ]
[ + - ][ - + ]
[ # # ]
917 : :
918 : : // Make sure passed sequence is in list
919 [ + - ][ + - ]: 33178 : const EntitySequence* seq2 = find( seq->start_handle() );
920 [ - + ]: 33178 : if( seq2 != seq ) return false;
921 : :
922 : : // Check all sequences referencing the same SequenceData
923 [ + - ]: 33178 : const SequenceData* data = seq->data();
924 [ + - ][ + - ]: 33178 : const_iterator i = lower_bound( data->start_handle() );
925 [ + - ][ - + ]: 33178 : if( i != data->seqManData.firstSequence ) return false;
926 : :
927 [ + - ][ + - ]: 33178 : if( i != begin() )
[ + + ]
928 : : {
929 : 19146 : const_iterator j = i;
930 [ + - ]: 19146 : --j;
931 [ + - ][ + - ]: 19146 : if( ( *j )->end_handle() >= data->start_handle() ) return false;
[ + - ][ - + ]
932 [ + - ][ + - ]: 19146 : if( ( *j )->data()->end_handle() >= data->start_handle() ) return false;
[ + - ][ + - ]
[ - + ]
933 : : }
934 : :
935 : : for( ;; )
936 : : {
937 [ + - ]: 6250727 : seq2 = *i;
938 [ + - ]: 6250727 : ++i;
939 [ + - ][ + - ]: 6250727 : if( i == end() ) return true;
[ + + ]
940 [ + - ][ + - ]: 6224071 : if( ( *i )->data() != data ) break;
[ + + ]
941 : :
942 [ + - ][ + - ]: 6217549 : if( seq2->end_handle() >= ( *i )->start_handle() ) return false;
[ + - ][ - + ]
943 : : }
944 : :
945 [ + - ][ + - ]: 6522 : if( ( *i )->start_handle() <= data->end_handle() ) return false;
[ + - ][ - + ]
946 [ + - ][ + - ]: 6522 : if( ( *i )->data()->start_handle() <= data->end_handle() ) return false;
[ + - ][ + - ]
[ - + ]
947 : :
948 : 6250727 : return true;
949 : : }
950 : :
951 : : #endif
952 : :
953 : : } // namespace moab
|