Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
SequenceManager.cpp
Go to the documentation of this file.
1 #include "SequenceManager.hpp"
2 #include "VertexSequence.hpp"
4 #include "ScdVertexData.hpp"
5 #include "MeshSetSequence.hpp"
6 #include "SweptElementSeq.hpp"
8 #include "moab/HomXform.hpp"
9 #include "PolyElementSeq.hpp"
10 #include "SysUtil.hpp"
11 #include "moab/Error.hpp"
12 
13 #include <cassert>
14 #include <new>
15 #include <algorithm>
16 
17 #ifndef NDEBUG
18 #include <iostream>
19 #endif
20 
21 namespace moab
22 {
23 
25 const EntityID SequenceManager::DEFAULT_ELEMENT_SEQUENCE_SIZE = DEFAULT_VERTEX_SEQUENCE_SIZE;
27 const EntityID SequenceManager::DEFAULT_MESHSET_SEQUENCE_SIZE = DEFAULT_VERTEX_SEQUENCE_SIZE;
28 
29 const int UNUSED_SIZE = 0;
30 
32 {
33  return std::max( DEFAULT_POLY_SEQUENCE_SIZE / conn_len, (EntityID)1 );
34 }
35 
37 {
38  // Release variable-length tag data
39  for( unsigned i = 0; i < tagSizes.size(); ++i )
40  if( tagSizes[i] == MB_VARIABLE_LENGTH ) release_tag_array( 0, i, false );
41 }
42 
44 {
45  // reset sequence multiplier
46  sequence_multiplier = 1.0;
47 
48  // Destroy all TypeSequenceManager instances
49  for( EntityType t = MBVERTEX; t < MBMAXTYPE; ++t )
51 
52  // Now re-create TypeSequenceManager instances
53  for( EntityType t = MBVERTEX; t < MBMAXTYPE; ++t )
54  new( typeData + t ) TypeSequenceManager();
55 }
56 
57 void SequenceManager::get_entities( Range& entities_out ) const
58 {
59  for( EntityType t = MBENTITYSET; t >= MBVERTEX; --t )
60  typeData[t].get_entities( entities_out );
61 }
62 
63 void SequenceManager::get_entities( std::vector< EntityHandle >& entities_out ) const
64 {
65  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
66  typeData[t].get_entities( entities_out );
67 }
68 
70 {
71  EntityID sum = 0;
72  for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t )
74 
75  return sum;
76 }
77 
79 {
80  ErrorCode rval;
82  for( i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
83  {
84  const EntityType type1 = TYPE_FROM_HANDLE( i->first );
85  const EntityType type2 = TYPE_FROM_HANDLE( i->second );
86  if( type1 == type2 )
87  {
88  rval = typeData[type1].check_valid_handles( NULL, i->first, i->second );
89  if( MB_SUCCESS != rval ) return rval;
90  }
91  else
92  {
93  int junk;
94  EntityHandle split = CREATE_HANDLE( type2, 0, junk );
95  rval = typeData[type1].check_valid_handles( NULL, i->first, split - 1 );
96  if( MB_SUCCESS != rval ) return rval;
97  rval = typeData[type2].check_valid_handles( NULL, split, i->second );
98  if( MB_SUCCESS != rval ) return rval;
99  }
100  }
101 
102  return MB_SUCCESS;
103 }
104 
106  const EntityHandle* entities,
107  size_t num_entities,
108  bool root_set_okay ) const
109 {
110  ErrorCode rval;
111  const EntitySequence* ptr = 0;
112 
113  const EntityHandle* const end = entities + num_entities;
114  for( ; entities < end; ++entities )
115  {
116  rval = find( *entities, ptr );
117  if( MB_SUCCESS != rval && !( root_set_okay && !*entities ) )
118  {
119  if( MB_ENTITY_NOT_FOUND == rval )
120  {
121  // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
122 #if 0
123  fprintf(stderr, "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)*entities);
124 #endif
125  }
126  return rval;
127  }
128  }
129 
130  return MB_SUCCESS;
131 }
132 
134 {
135  return typeData[TYPE_FROM_HANDLE( entity )].erase( NULL, entity );
136 }
137 
139 {
140  ErrorCode rval = check_valid_entities( NULL, entities );
141  if( MB_SUCCESS != rval ) return rval;
142 
143  ErrorCode result = MB_SUCCESS;
145  for( i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
146  {
147  const EntityType type1 = TYPE_FROM_HANDLE( i->first );
148  const EntityType type2 = TYPE_FROM_HANDLE( i->second );
149  if( type1 == type2 )
150  {
151  rval = typeData[type1].erase( NULL, i->first, i->second );
152  if( MB_SUCCESS != rval ) return result = rval;
153  }
154  else
155  {
156  int junk;
157  EntityHandle split = CREATE_HANDLE( type2, 0, junk );
158  rval = typeData[type1].erase( NULL, i->first, split - 1 );
159  if( MB_SUCCESS != rval ) return result = rval;
160  rval = typeData[type2].erase( NULL, split, i->second );
161  if( MB_SUCCESS != rval ) return result = rval;
162  }
163  }
164 
165  return result;
166 }
167 
168 ErrorCode SequenceManager::create_vertex( const double coords[3], EntityHandle& handle )
169 {
172  bool append;
174  VertexSequence* vseq;
175 
176  if( seq == typeData[MBVERTEX].end() )
177  {
178  SequenceData* seq_data = 0;
179  EntityID seq_data_size = 0;
180  handle =
181  typeData[MBVERTEX].find_free_sequence( DEFAULT_VERTEX_SEQUENCE_SIZE, start, end, seq_data, seq_data_size );
182  if( !handle ) return MB_FAILURE;
183 
184  if( seq_data )
185  vseq = new VertexSequence( handle, 1, seq_data );
186  else
187  vseq = new VertexSequence( handle, 1, DEFAULT_VERTEX_SEQUENCE_SIZE );
188 
189  ErrorCode rval = typeData[MBVERTEX].insert_sequence( vseq );
190  if( MB_SUCCESS != rval )
191  {
192  SequenceData* vdata = vseq->data();
193  delete vseq;
194  if( !seq_data ) delete vdata;
195 
196  return rval;
197  }
198  }
199  else
200  {
201  vseq = reinterpret_cast< VertexSequence* >( *seq );
202  if( append )
203  {
204  vseq->push_back( 1 );
205  handle = vseq->end_handle();
207  }
208  else
209  {
210  vseq->push_front( 1 );
211  handle = vseq->start_handle();
213  }
214  }
215 
216  return vseq->set_coordinates( handle, coords );
217 }
218 
220  const EntityHandle* conn,
221  unsigned conn_len,
222  EntityHandle& handle )
223 {
224  if( type <= MBVERTEX || type >= MBENTITYSET ) return MB_TYPE_OUT_OF_RANGE;
225 
226  const EntityHandle start = CREATE_HANDLE( type, MB_START_ID );
227  const EntityHandle end = CREATE_HANDLE( type, MB_END_ID );
228  bool append;
229  TypeSequenceManager::iterator seq = typeData[type].find_free_handle( start, end, append, conn_len );
230  UnstructuredElemSeq* eseq;
231 
232  if( seq == typeData[type].end() )
233  {
234  SequenceData* seq_data = 0;
236  if( type == MBPOLYGON || type == MBPOLYHEDRON )
237  {
238  size = default_poly_sequence_size( conn_len );
239  }
240  EntityID seq_data_size = 0;
241  handle = typeData[type].find_free_sequence( size, start, end, seq_data, seq_data_size, conn_len );
242  if( !handle ) return MB_FAILURE;
243 
244  if( MBPOLYGON == type || MBPOLYHEDRON == type )
245  {
246  if( seq_data )
247  eseq = new PolyElementSeq( handle, 1, conn_len, seq_data );
248  else
249  eseq = new PolyElementSeq( handle, 1, conn_len, size );
250  }
251  else
252  {
253  if( seq_data )
254  eseq = new UnstructuredElemSeq( handle, 1, conn_len, seq_data );
255  else
256  eseq = new UnstructuredElemSeq( handle, 1, conn_len, size );
257  }
258 
259  ErrorCode rval = typeData[type].insert_sequence( eseq );
260  if( MB_SUCCESS != rval )
261  {
262  SequenceData* vdata = eseq->data();
263  delete eseq;
264  if( !seq_data ) delete vdata;
265 
266  return rval;
267  }
268  }
269  else
270  {
271  eseq = reinterpret_cast< UnstructuredElemSeq* >( *seq );
272  if( append )
273  {
274  eseq->push_back( 1 );
275  handle = eseq->end_handle();
276  typeData[type].notify_appended( seq );
277  }
278  else
279  {
280  eseq->push_front( 1 );
281  handle = eseq->start_handle();
282  typeData[type].notify_prepended( seq );
283  }
284  }
285 
286  return eseq->set_connectivity( handle, conn, conn_len );
287 }
288 
290 {
293  bool append;
295  MeshSetSequence* msseq;
296 
297  if( seq == typeData[MBENTITYSET].end() )
298  {
299  SequenceData* seq_data = 0;
300  EntityID seq_data_size = 0;
301  handle = typeData[MBENTITYSET].find_free_sequence( DEFAULT_MESHSET_SEQUENCE_SIZE, start, end, seq_data,
302  seq_data_size );
303  if( !handle ) return MB_FAILURE;
304 
305  if( seq_data )
306  msseq = new MeshSetSequence( handle, 1, flags, seq_data );
307  else
308  msseq = new MeshSetSequence( handle, 1, flags, DEFAULT_MESHSET_SEQUENCE_SIZE );
309 
311  if( MB_SUCCESS != rval )
312  {
313  SequenceData* vdata = msseq->data();
314  delete msseq;
315  if( !seq_data ) delete vdata;
316 
317  return rval;
318  }
319  }
320  else
321  {
322  msseq = reinterpret_cast< MeshSetSequence* >( *seq );
323  if( append )
324  {
325  msseq->push_back( 1, &flags );
326  handle = msseq->end_handle();
328  }
329  else
330  {
331  msseq->push_front( 1, &flags );
332  handle = msseq->start_handle();
334  }
335  }
336 
337  return MB_SUCCESS;
338 }
339 
341 {
342  SequenceData* data = 0;
344  EntityHandle block_start = 1, block_end = 0;
345  ErrorCode rval = typeData[MBENTITYSET].is_free_handle( handle, seqptr, data, block_start, block_end );
346  if( MB_SUCCESS != rval ) return rval;
347 
348  MeshSetSequence* seq;
349  if( seqptr != typeData[MBENTITYSET].end() )
350  {
351  seq = static_cast< MeshSetSequence* >( *seqptr );
352  if( seq->start_handle() - 1 == handle )
353  {
354  rval = seq->push_front( 1, &flags );
355  if( MB_SUCCESS == rval )
356  {
357  rval = typeData[MBENTITYSET].notify_prepended( seqptr );
358  if( MB_SUCCESS != rval ) seq->pop_front( 1 );
359  }
360  return rval;
361  }
362  else if( seq->end_handle() + 1 == handle )
363  {
364  rval = seq->push_back( 1, &flags );
365  if( MB_SUCCESS == rval )
366  {
367  rval = typeData[MBENTITYSET].notify_appended( seqptr );
368  if( MB_SUCCESS != rval ) seq->pop_back( 1 );
369  }
370  return rval;
371  }
372  else
373  return MB_FAILURE; // Should be unreachable
374  }
375  else
376  {
377  if( data )
378  {
379  seq = new MeshSetSequence( handle, 1, flags, data );
380  }
381  else
382  {
383  assert( handle >= block_start && handle <= block_end );
385  seq = new MeshSetSequence( handle, 1, flags, block_end - handle + 1 );
386  }
387 
388  rval = typeData[MBENTITYSET].insert_sequence( seq );
389  if( MB_SUCCESS != rval )
390  {
391  SequenceData* vdata = seq->data();
392  delete seq;
393  if( !data ) delete vdata;
394  return rval;
395  }
396 
397  return MB_SUCCESS;
398  }
399 }
400 
401 void SequenceManager::trim_sequence_block( EntityHandle start_handle, EntityHandle& end_handle, unsigned max_size )
402 {
403  assert( end_handle >= start_handle );
404  assert( (int)max_size > 0 ); // Cast to int also prohibits some ridiculously large values
405 
406  // If input range is larger than preferred size, trim it
407  if( end_handle - start_handle >= max_size ) end_handle = start_handle + max_size - 1;
408 }
409 
411  EntityID count,
412  int size,
413  EntityID start,
414  SequenceData*& data,
415  EntityID& data_size )
416 {
417  TypeSequenceManager& tsm = typeData[type];
418  data = 0;
419  EntityHandle handle = CREATE_HANDLE( type, start );
420  if( start < MB_START_ID || !tsm.is_free_sequence( handle, count, data, size ) )
421  {
422  EntityHandle pstart = CREATE_HANDLE( type, MB_START_ID );
423  EntityHandle pend = CREATE_HANDLE( type, MB_END_ID );
424  handle = tsm.find_free_sequence( count, pstart, pend, data, data_size, size );
425  }
426 
427  return handle;
428 }
429 
430 EntityID SequenceManager::new_sequence_size( EntityHandle start, EntityID requested_size, int sequence_size ) const
431 {
432 
433  requested_size = (EntityID)( this->sequence_multiplier * requested_size );
434 
435  if( sequence_size < (int)requested_size ) return requested_size;
436 
437  EntityHandle last = typeData[TYPE_FROM_HANDLE( start )].last_free_handle( start );
438  if( !last )
439  {
440  assert( false );
441  return 0;
442  }
443 
444  EntityID available_size = last - start + 1;
445  if( sequence_size < available_size )
446  return sequence_size;
447  else
448  return available_size;
449 }
450 
452  EntityID count,
453  int size,
454  EntityID start,
455  EntityHandle& handle,
456  EntitySequence*& sequence,
457  int sequence_size )
458 {
459  SequenceData* data = NULL;
460  EntityID data_size = 0;
461  handle = sequence_start_handle( type, count, size, start, data, data_size );
462 
463  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
464 
465  switch( type )
466  {
467  case MBENTITYSET:
468  case MBMAXTYPE:
469  return MB_TYPE_OUT_OF_RANGE;
470 
471  case MBVERTEX:
472  if( size != 0 ) return MB_INDEX_OUT_OF_RANGE;
473 
474  if( data )
475  sequence = new VertexSequence( handle, count, data );
476  else
477  {
478  if( !data_size ) data_size = new_sequence_size( handle, count, sequence_size );
479  sequence = new VertexSequence( handle, count, data_size );
480  }
481  break;
482 
483  case MBPOLYGON:
484  case MBPOLYHEDRON:
485  if( size == 0 ) return MB_INDEX_OUT_OF_RANGE;
486 
487  if( data )
488  sequence = new PolyElementSeq( handle, count, size, data );
489  else
490  {
491  if( !data_size )
492  data_size = new_sequence_size(
493  handle, count, ( -1 == sequence_size ? default_poly_sequence_size( size ) : sequence_size ) );
494  sequence = new PolyElementSeq( handle, count, size, data_size );
495  }
496  break;
497 
498  default:
499  if( size == 0 ) return MB_INDEX_OUT_OF_RANGE;
500 
501  if( data )
502  sequence = new UnstructuredElemSeq( handle, count, size, data );
503  else
504  {
505  if( !data_size ) data_size = new_sequence_size( handle, count, sequence_size );
506  sequence = new UnstructuredElemSeq( handle, count, size, data_size );
507  }
508  // tjt calling new_sequence_size 'cuz don't have a sequence data;
509  // start 41467, count 246
510  break;
511  }
512 
513  ErrorCode result = typeData[type].insert_sequence( sequence );
514  if( MB_SUCCESS != result )
515  {
516  // Change to NULL if had an existing data or if no existing data,
517  // change to the new data created
518  data = data ? 0 : sequence->data();
519  delete sequence;
520  delete data;
521  return result;
522  }
523 
524  return MB_SUCCESS;
525 }
526 
528  EntityID start,
529  const unsigned* flags,
530  EntityHandle& handle,
531  EntitySequence*& sequence )
532 {
533  SequenceData* data = 0;
534  EntityID data_size = 0;
535  handle = sequence_start_handle( MBENTITYSET, count, 0, start, data, data_size );
536 
537  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
538 
539  if( data )
540  sequence = new MeshSetSequence( handle, count, flags, data );
541  else
542  sequence = new MeshSetSequence( handle, count, flags, count );
543 
544  ErrorCode result = typeData[MBENTITYSET].insert_sequence( sequence );
545  if( MB_SUCCESS != result )
546  {
547  // Change to NULL if had an existing data or if no existing data,
548  // change to the new data created
549  data = data ? 0 : sequence->data();
550  delete sequence;
551  delete data;
552  return result;
553  }
554 
555  return MB_SUCCESS;
556 }
557 
559  EntityID start,
560  unsigned flags,
561  EntityHandle& handle,
562  EntitySequence*& sequence )
563 {
564  SequenceData* data = 0;
565  EntityID data_size = 0;
566  handle = sequence_start_handle( MBENTITYSET, count, 0, start, data, data_size );
567  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
568 
569  if( data )
570  sequence = new MeshSetSequence( handle, count, flags, data );
571  else
572  sequence = new MeshSetSequence( handle, count, flags, count );
573 
574  ErrorCode result = typeData[MBENTITYSET].insert_sequence( sequence );
575  if( MB_SUCCESS != result )
576  {
577  // Change to NULL if had an existing data or if no existing data,
578  // change to the new data created
579  data = data ? 0 : sequence->data();
580  delete sequence;
581  delete data;
582  return result;
583  }
584 
585  return MB_SUCCESS;
586 }
587 
589  int jmin,
590  int kmin,
591  int imax,
592  int jmax,
593  int kmax,
594  EntityType type,
595  EntityID start_id_hint,
596  EntityHandle& handle,
597  EntitySequence*& sequence,
598  int* is_periodic )
599 {
600  int this_dim = CN::Dimension( type );
601 
602  // Use > instead of != in the following assert to also catch cases where imin > imax, etc.
603  assert( ( this_dim < 3 || kmax > kmin ) && ( this_dim < 2 || jmax > jmin ) && ( this_dim < 1 || imax > imin ) );
604 
605  // Compute # entities; not as easy as it would appear...
606  EntityID num_ent;
607  if( MBVERTEX == type )
608  num_ent = (EntityID)( imax - imin + 1 ) * (EntityID)( jmax - jmin + 1 ) * (EntityID)( kmax - kmin + 1 );
609  else
610  {
611  num_ent = ( imax - imin + ( is_periodic && is_periodic[0] ? 1 : 0 ) ) *
612  ( this_dim >= 2 ? ( jmax - jmin + ( is_periodic && is_periodic[1] ? 1 : 0 ) ) : 1 ) *
613  ( this_dim >= 3 ? ( kmax - kmin ) : 1 );
614  }
615 
616  if( MBVERTEX == type && ( is_periodic && ( is_periodic[0] || is_periodic[1] ) ) ) return MB_FAILURE;
617 
618  // Get a start handle
619  SequenceData* data = 0;
620  EntityID data_size = 0;
621  handle = sequence_start_handle( type, num_ent, -1, start_id_hint, data, data_size );
622 
623  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
624  assert( !data );
625 
626  switch( type )
627  {
628  case MBVERTEX:
629  data = new ScdVertexData( handle, imin, jmin, kmin, imax, jmax, kmax );
630  sequence = new VertexSequence( handle, data->size(), data );
631  break;
632  case MBEDGE:
633  case MBQUAD:
634  case MBHEX:
635  sequence = new StructuredElementSeq( handle, imin, jmin, kmin, imax, jmax, kmax, is_periodic );
636  break;
637  default:
638  return MB_TYPE_OUT_OF_RANGE;
639  }
640 
641  ErrorCode result = typeData[type].insert_sequence( sequence );
642  if( MB_SUCCESS != result )
643  {
644  data = sequence->data();
645  delete sequence;
646  delete data;
647  return result;
648  }
649 
650  return MB_SUCCESS;
651 }
652 
654  const HomCoord& coord_max,
655  EntityType type,
656  EntityID start_id_hint,
657  EntityHandle& first_handle_out,
658  EntitySequence*& sequence_out,
659  int* is_periodic )
660 {
661  return create_scd_sequence( coord_min.i(), coord_min.j(), coord_min.k(), coord_max.i(), coord_max.j(),
662  coord_max.k(), type, start_id_hint, first_handle_out, sequence_out, is_periodic );
663 }
664 
666  int jmin,
667  int kmin,
668  int imax,
669  int jmax,
670  int kmax,
671  int* Cq,
672  EntityType type,
673  EntityID start_id_hint,
674  EntityHandle& handle,
675  EntitySequence*& sequence )
676 {
677  int this_dim = CN::Dimension( type );
678 
679  assert( ( this_dim < 3 || kmax > kmin ) && ( this_dim < 2 || jmax > jmin ) && ( this_dim < 1 || imax > imin ) );
680 
681  EntityID num_ent;
682  if( MBVERTEX == type )
683  num_ent = (EntityID)( imax - imin + 1 ) * (EntityID)( jmax - jmin + 1 ) * (EntityID)( kmax - kmin + 1 );
684  else
685  {
686  num_ent = ( imax - imin ) * ( this_dim >= 2 ? ( jmax - jmin ) : 1 ) * ( this_dim >= 3 ? ( kmax - kmin ) : 1 );
687  }
688 
689  // Get a start handle
690  SequenceData* data = 0;
691  EntityID data_size = 0;
692  handle = sequence_start_handle( type, num_ent, -1, start_id_hint, data, data_size );
693 
694  if( !handle ) return MB_MEMORY_ALLOCATION_FAILED;
695  assert( !data );
696 
697  switch( type )
698  {
699  case MBVERTEX:
700  data = new ScdVertexData( handle, imin, jmin, kmin, imax, jmax, kmax );
701  sequence = new VertexSequence( handle, data->size(), data );
702  break;
703  case MBEDGE:
704  case MBQUAD:
705  case MBHEX:
706  sequence = new SweptElementSeq( handle, imin, jmin, kmin, imax, jmax, kmax, Cq );
707  break;
708  default:
709  return MB_TYPE_OUT_OF_RANGE;
710  }
711 
712  ErrorCode result = typeData[type].insert_sequence( sequence );
713  if( MB_SUCCESS != result )
714  {
715  data = sequence->data();
716  delete sequence;
717  delete data;
718  return result;
719  }
720 
721  return MB_SUCCESS;
722 }
723 
725  const HomCoord& coord_max,
726  int* Cq,
727  EntityType type,
728  EntityID start_id_hint,
729  EntityHandle& first_handle_out,
730  EntitySequence*& sequence_out )
731 {
732  return create_sweep_sequence( coord_min.i(), coord_min.j(), coord_min.k(), coord_max.i(), coord_max.j(),
733  coord_max.k(), Cq, type, start_id_hint, first_handle_out, sequence_out );
734 }
735 
737  EntitySequence* elem_seq,
738  const HomCoord& p1,
739  const HomCoord& q1,
740  const HomCoord& p2,
741  const HomCoord& q2,
742  const HomCoord& p3,
743  const HomCoord& q3,
744  bool bb_input,
745  const HomCoord* bb_min,
746  const HomCoord* bb_max )
747 {
748  // Check first that they're structured vtx/elem sequences
749  ScdVertexData* scd_vd = dynamic_cast< ScdVertexData* >( vert_seq->data() );
750  if( !scd_vd ) return MB_FAILURE;
751 
752  ScdElementData* scd_ed = dynamic_cast< ScdElementData* >( elem_seq->data() );
753  if( !scd_ed ) return MB_FAILURE;
754 
755  if( bb_min && bb_max )
756  return scd_ed->add_vsequence( scd_vd, p1, q1, p2, q2, p3, q3, bb_input, *bb_min, *bb_max );
757  else
758  return scd_ed->add_vsequence( scd_vd, p1, q1, p2, q2, p3, q3, bb_input, HomCoord::unitv[0],
759  HomCoord::unitv[0] );
760 }
761 
763 {
764  const EntityType type = TYPE_FROM_HANDLE( new_seq->start_handle() );
765  return typeData[type].replace_subsequence( new_seq, &tagSizes[0], tagSizes.size() );
766 }
767 
768 void SequenceManager::get_memory_use( unsigned long long& total_entity_storage,
769  unsigned long long& total_storage ) const
770 
771 {
772  total_entity_storage = 0;
773  total_storage = 0;
774  unsigned long long temp_entity, temp_total;
775  for( EntityType i = MBVERTEX; i < MBMAXTYPE; ++i )
776  {
777  temp_entity = temp_total = 0;
778  get_memory_use( i, temp_entity, temp_total );
779  total_entity_storage += temp_entity;
780  total_storage += temp_total;
781  }
782 }
783 
784 void SequenceManager::get_memory_use( EntityType type,
785  unsigned long long& total_entity_storage,
786  unsigned long long& total_storage ) const
787 {
788  typeData[type].get_memory_use( total_entity_storage, total_storage );
789 }
790 
792  unsigned long long& total_entity_storage,
793  unsigned long long& total_amortized_storage ) const
794 {
795  total_entity_storage = 0;
796  total_amortized_storage = 0;
797  unsigned long long temp_entity, temp_total;
799  for( i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
800  {
801  const EntityType t1 = TYPE_FROM_HANDLE( i->first );
802  const EntityType t2 = TYPE_FROM_HANDLE( i->second );
803  if( t1 == t2 )
804  {
805  temp_entity = temp_total = 0;
806  typeData[t1].get_memory_use( i->first, i->second, temp_entity, temp_total );
807  total_entity_storage += temp_entity;
808  total_amortized_storage += temp_total;
809  }
810  else
811  {
812  int junk;
813 
814  temp_entity = temp_total = 0;
815  typeData[t1].get_memory_use( i->first, CREATE_HANDLE( t1, MB_END_ID, junk ), temp_entity, temp_total );
816  total_entity_storage += temp_entity;
817  total_amortized_storage += temp_total;
818 
819  temp_entity = temp_total = 0;
820  typeData[t2].get_memory_use( CREATE_HANDLE( t2, MB_START_ID, junk ), i->second, temp_entity, temp_total );
821  total_entity_storage += temp_entity;
822  total_amortized_storage += temp_total;
823  }
824  }
825 }
826 
827 ErrorCode SequenceManager::reserve_tag_array( Error* /* error_handler */, int size, int& index )
828 {
829  if( size < 1 && size != MB_VARIABLE_LENGTH )
830  {
831  MB_SET_ERR( MB_INVALID_SIZE, "Invalid tag size: " << size );
832  }
833 
834  std::vector< int >::iterator i = std::find( tagSizes.begin(), tagSizes.end(), UNUSED_SIZE );
835  if( i == tagSizes.end() )
836  {
837  index = tagSizes.size();
838  tagSizes.push_back( size );
839  }
840  else
841  {
842  index = i - tagSizes.begin();
843  *i = size;
844  }
845 
846  return MB_SUCCESS;
847 }
848 
849 ErrorCode SequenceManager::release_tag_array( Error* /* error_handler */, int index, bool release_id )
850 {
851  if( (unsigned)index >= tagSizes.size() || UNUSED_SIZE == tagSizes[index] )
852  {
853  // MB_TAG_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
854 #if 0
855  fprintf(stderr, "[Warning]: Invalid dense tag index: %d\n", index);
856 #endif
857  return MB_TAG_NOT_FOUND;
858  }
859 
860  for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
861  {
862  TypeSequenceManager& seqs = entity_map( t );
863  for( TypeSequenceManager::iterator i = seqs.begin(); i != seqs.end(); ++i )
864  ( *i )->data()->release_tag_data( index, tagSizes[index] );
865  }
866 
867  if( release_id ) tagSizes[index] = UNUSED_SIZE;
868 
869  return MB_SUCCESS;
870 }
871 
872 // These are meant to be called from the debugger (not declared in any header)
873 // so leave them out of release builds (-DNDEBUG).
874 #ifndef NDEBUG
875 
876 std::ostream& operator<<( std::ostream& s, const TypeSequenceManager& seq_man )
877 {
878  const SequenceData* prev_data = 0;
879  for( TypeSequenceManager::const_iterator i = seq_man.begin(); i != seq_man.end(); ++i )
880  {
881  const EntitySequence* seq = *i;
882  if( seq->data() != prev_data )
883  {
884  prev_data = seq->data();
885  s << "SequenceData [" << ID_FROM_HANDLE( seq->data()->start_handle() ) << ","
886  << ID_FROM_HANDLE( seq->data()->end_handle() ) << "]" << std::endl;
887  }
888  s << " Sequence [" << ID_FROM_HANDLE( seq->start_handle() ) << "," << ID_FROM_HANDLE( seq->end_handle() )
889  << "]" << std::endl;
890  }
891 
892  return s;
893 }
894 
895 std::ostream& operator<<( std::ostream& s, const SequenceManager& seq_man )
896 {
897  for( EntityType t = MBVERTEX; t < MBMAXTYPE; ++t )
898  {
899  if( !seq_man.entity_map( t ).empty() )
900  s << std::endl
901  << "****************** " << CN::EntityTypeName( t ) << " ******************" << std::endl
902  << seq_man.entity_map( t ) << std::endl;
903  }
904 
905  return s;
906 }
907 
908 void print_sequences( const SequenceManager& seqman )
909 {
910  std::cout << seqman << std::endl;
911 }
912 
914 {
915  std::cout << seqman << std::endl;
916 }
917 
918 #endif
919 
920 } // namespace moab