Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
moab::TypeSequenceManager Class Reference

Maintain data structures organizing EntitySequence instances. More...

#include <TypeSequenceManager.hpp>

+ Collaboration diagram for moab::TypeSequenceManager:

Classes

class  DummySequence
 Dummy EntitySequence for use in querying set container. More...
 
class  SequenceCompare
 Comparison function used in std::set. More...
 
struct  SequenceDataPtr
 

Public Types

typedef std::set< EntitySequence *, SequenceCompare< EntitySequence > > set_type
 Type of container for organizing EntitySequence instances. More...
 
typedef set_type::iterator iterator
 Iterator for set_type. More...
 
typedef set_type::const_iterator const_iterator
 Iterator for set_type. More...
 
typedef std::set< SequenceData *, SequenceCompare< SequenceData > > data_set_type
 Type of container for organizing SequenceData instances. More...
 
typedef data_set_type::iterator data_iterator
 iterator type for data_set_type More...
 

Public Member Functions

ErrorCode insert_sequence (EntitySequence *seq_ptr)
 Add an entity sequence. More...
 
ErrorCode remove_sequence (const EntitySequence *seq_ptr, bool &is_last_user_of_sequence_data)
 Remove an entity sequence. More...
 
ErrorCode replace_subsequence (EntitySequence *seq_ptr, const int *tag_sizes, int num_tag_sizes)
 Replace sequence or subset of sequence. More...
 
 TypeSequenceManager ()
 
 ~TypeSequenceManager ()
 
const_iterator begin () const
 Start of EntitySequence set. More...
 
iterator begin ()
 
const_iterator end () const
 End of EntitySequence set. More...
 
iterator end ()
 
const_iterator lower_bound (EntityHandle h) const
 Return EntitySequence for specified handle. More...
 
iterator lower_bound (EntityHandle h)
 
const_iterator upper_bound (EntityHandle h) const
 Return EntitySequence after specified handle. More...
 
EntitySequencefind (EntityHandle h) const
 Get EntitySequence for handle. More...
 
EntitySequencefind (EntityHandle h)
 
ErrorCode find (EntityHandle h, EntitySequence *&)
 
ErrorCode find (EntityHandle h, const EntitySequence *&) const
 
const EntitySequenceget_last_accessed () const
 
void get_entities (Range &entities_out) const
 Get handles for all entities in all sequences. More...
 
void get_entities (std::vector< EntityHandle > &entities_out) const
 Get handles for all entities in all sequences. More...
 
EntityID get_number_entities () const
 Get number of entities represented by all sequences. More...
 
ErrorCode check_valid_handles (Error *error_handler, EntityHandle first, EntityHandle last) const
 
ErrorCode erase (Error *error_handler, EntityHandle first, EntityHandle last)
 Remove entities. More...
 
ErrorCode erase (Error *error_handler, EntityHandle entity)
 
bool empty () const
 Test if this instance contains no sequences. More...
 
iterator find_free_handle (EntityHandle min_start_handle, EntityHandle max_end_handle, bool &append_out, int values_per_ent=0)
 Allocate a handle in an existing entity sequence. More...
 
EntityHandle find_free_block (EntityID num_entities, EntityHandle min_start_handle, EntityHandle max_end_handle)
 Find block of free handles. More...
 
EntityHandle find_free_sequence (EntityID num_entities, EntityHandle min_start_handle, EntityHandle max_end_handle, SequenceData *&sequence_data_out, EntityID &sequence_data_size, int values_per_ent=0)
 Find block of free handles. More...
 
bool is_free_sequence (EntityHandle start_handle, EntityID num_entities, SequenceData *&sequence_data_out, int values_per_ent=0)
 Check if block of handles is free. More...
 
ErrorCode is_free_handle (EntityHandle handle, iterator &seq_ptr_out, SequenceData *&data_ptr_out, EntityHandle &block_start, EntityHandle &block_end, int values_per_ent=0)
 Check if specific handle is free for allocation. More...
 
EntityHandle last_free_handle (EntityHandle after_this) const
 
ErrorCode notify_prepended (iterator seq)
 Notify that sequence was prepended to. More...
 
ErrorCode notify_appended (iterator seq)
 Notify that sequence was appended to. More...
 
void get_memory_use (unsigned long long &total_entity_storage, unsigned long long &total_storage) const
 
void get_memory_use (EntityHandle start, EntityHandle end, unsigned long long &total_entity_storage, unsigned long long &total_amortized_storage) const
 
unsigned long get_sequence_count () const
 
EntityID get_occupied_size (const SequenceData *) const
 Get used size of SequenceData. More...
 

Private Member Functions

iterator erase (iterator i)
 Remove a sequence. More...
 
iterator split_sequence (iterator i, EntityHandle h)
 split a sequence More...
 
void append_memory_use (EntityHandle first, EntityHandle last, const SequenceData *data, unsigned long long &entity_storage, unsigned long long &total_storage) const
 
ErrorCode check_merge_next (iterator i)
 
ErrorCode check_merge_prev (iterator i)
 
ErrorCode merge_internal (iterator keep, iterator dead)
 
bool check_valid_data (const EntitySequence *seq) const
 

Private Attributes

EntitySequencelastReferenced
 Last accessed EntitySequence - Null only if no sequences. More...
 
set_type sequenceSet
 Set of all managed EntitySequence instances. More...
 
data_set_type availableList
 SequenceData containing unused entries. More...
 

Detailed Description

Maintain data structures organizing EntitySequence instances.

EntitySequenceManager is a composition of instances of TypeSequenceManager, one instance for each EntityType. The TypeSequenceManager provides organization, ownership, and querying of EntitySequences for a specific EntityType.

Definition at line 22 of file TypeSequenceManager.hpp.

Member Typedef Documentation

◆ const_iterator

typedef set_type::const_iterator moab::TypeSequenceManager::const_iterator

Iterator for set_type.

Definition at line 69 of file TypeSequenceManager.hpp.

◆ data_iterator

typedef data_set_type::iterator moab::TypeSequenceManager::data_iterator

iterator type for data_set_type

Definition at line 73 of file TypeSequenceManager.hpp.

◆ data_set_type

Type of container for organizing SequenceData instances.

Definition at line 71 of file TypeSequenceManager.hpp.

◆ iterator

typedef set_type::iterator moab::TypeSequenceManager::iterator

Iterator for set_type.

Definition at line 67 of file TypeSequenceManager.hpp.

◆ set_type

Type of container for organizing EntitySequence instances.

Definition at line 65 of file TypeSequenceManager.hpp.

Constructor & Destructor Documentation

◆ TypeSequenceManager()

moab::TypeSequenceManager::TypeSequenceManager ( )
inline

Definition at line 147 of file TypeSequenceManager.hpp.

147 : lastReferenced( 0 ) {}

◆ ~TypeSequenceManager()

moab::TypeSequenceManager::~TypeSequenceManager ( )

Definition at line 10 of file TypeSequenceManager.cpp.

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  for( iterator i = begin(); i != end(); ++i )
21  {
22  EntitySequence* seq = *i;
23  // Check for case b) above
24  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  SequenceData* data = seq->data();
30  delete seq;
31  delete data;
32  }
33  else
34  {
35  delete seq;
36  }
37  }
38  sequenceSet.clear();
39 
40  // Case a) above
41  for( data_iterator i = availableList.begin(); i != availableList.end(); ++i )
42  delete *i;
43  availableList.clear();
44 }

References availableList, begin(), moab::EntitySequence::data(), end(), sequenceSet, and moab::EntitySequence::using_entire_data().

Member Function Documentation

◆ append_memory_use()

void moab::TypeSequenceManager::append_memory_use ( EntityHandle  first,
EntityHandle  last,
const SequenceData data,
unsigned long long &  entity_storage,
unsigned long long &  total_storage 
) const
private

Definition at line 852 of file TypeSequenceManager.cpp.

857 {
858  const unsigned long allocated_count = data->size();
859 
860  unsigned long bytes_per_ent, seq_size;
861  const_iterator i = data->seqManData.firstSequence;
862  ( *i )->get_const_memory_use( bytes_per_ent, seq_size );
863 
864  unsigned long other_ent_mem = 0;
865  unsigned long occupied_count = 0, entity_count = 0, sequence_count = 0;
866  for( ; i != end() && ( *i )->data() == data; ++i )
867  {
868  occupied_count += ( *i )->size();
869  ++sequence_count;
870 
871  EntityHandle start = std::max( first, ( *i )->start_handle() );
872  EntityHandle stop = std::min( last, ( *i )->end_handle() );
873  if( stop < start ) continue;
874 
875  entity_count += stop - start + 1;
876  other_ent_mem += ( *i )->get_per_entity_memory_use( start, stop );
877  }
878 
879  unsigned long sum = sequence_count * seq_size + allocated_count * bytes_per_ent;
880 
881  // Watch for overflow
882  assert( entity_count > 0 && occupied_count > 0 && allocated_count > 0 );
883  if( std::numeric_limits< unsigned long >::max() / entity_count <= sum )
884  {
885  total_storage += sum * ( entity_count / occupied_count ) + other_ent_mem;
886  entity_storage += sum * ( entity_count / allocated_count ) + other_ent_mem;
887  }
888  else
889  {
890  total_storage += sum * entity_count / occupied_count + other_ent_mem;
891  entity_storage += sum * entity_count / allocated_count + other_ent_mem;
892  }
893 }

References end(), moab::GeomUtil::first(), moab::TypeSequenceManager::SequenceDataPtr::firstSequence, moab::SequenceData::seqManData, moab::SequenceData::size(), and moab::sum().

Referenced by get_memory_use().

◆ begin() [1/2]

iterator moab::TypeSequenceManager::begin ( )
inline

Definition at line 156 of file TypeSequenceManager.hpp.

157  {
158  return sequenceSet.begin();
159  }

References sequenceSet.

◆ begin() [2/2]

◆ check_merge_next()

ErrorCode moab::TypeSequenceManager::check_merge_next ( iterator  i)
private

Definition at line 67 of file TypeSequenceManager.cpp.

68 {
69  iterator j = i;
70  ++j;
71  if( j == end() || ( *j )->data() != ( *i )->data() || ( *j )->start_handle() > ( *i )->end_handle() + 1 )
72  return MB_SUCCESS;
73 
74  assert( ( *i )->end_handle() + 1 == ( *j )->start_handle() );
75  return merge_internal( i, j );
76 }

References end(), MB_SUCCESS, and merge_internal().

Referenced by insert_sequence(), and notify_appended().

◆ check_merge_prev()

ErrorCode moab::TypeSequenceManager::check_merge_prev ( iterator  i)
private

Definition at line 78 of file TypeSequenceManager.cpp.

79 {
80  if( i == begin() ) return MB_SUCCESS;
81 
82  iterator j = i;
83  --j;
84  if( ( *j )->data() != ( *i )->data() || ( *j )->end_handle() + 1 < ( *i )->start_handle() ) return MB_SUCCESS;
85 
86  assert( ( *j )->end_handle() + 1 == ( *i )->start_handle() );
87  return merge_internal( i, j );
88 }

References begin(), MB_SUCCESS, and merge_internal().

Referenced by insert_sequence(), and notify_prepended().

◆ check_valid_data()

bool moab::TypeSequenceManager::check_valid_data ( const EntitySequence seq) const
private

Definition at line 926 of file TypeSequenceManager.cpp.

927 {
928  // Caller passed a sequence that should be contained, so cannot be empty
929  if( empty() ) return false;
930 
931  // Make sure lastReferenced points to something
932  if( !lastReferenced ) return false;
933 
934  const_iterator seqi = sequenceSet.lower_bound( lastReferenced );
935  if( seqi == sequenceSet.end() || *seqi != lastReferenced ) return false;
936 
937  // Make sure passed sequence is in list
938  const EntitySequence* seq2 = find( seq->start_handle() );
939  if( seq2 != seq ) return false;
940 
941  // Check all sequences referencing the same SequenceData
942  const SequenceData* data = seq->data();
943  const_iterator i = lower_bound( data->start_handle() );
944  if( i != data->seqManData.firstSequence ) return false;
945 
946  if( i != begin() )
947  {
948  const_iterator j = i;
949  --j;
950  if( ( *j )->end_handle() >= data->start_handle() ) return false;
951  if( ( *j )->data()->end_handle() >= data->start_handle() ) return false;
952  }
953 
954  for( ;; )
955  {
956  seq2 = *i;
957  ++i;
958  if( i == end() ) return true;
959  if( ( *i )->data() != data ) break;
960 
961  if( seq2->end_handle() >= ( *i )->start_handle() ) return false;
962  }
963 
964  if( ( *i )->start_handle() <= data->end_handle() ) return false;
965  if( ( *i )->data()->start_handle() <= data->end_handle() ) return false;
966 
967  return true;
968 }

References begin(), moab::EntitySequence::data(), empty(), end(), moab::EntitySequence::end_handle(), moab::SequenceData::end_handle(), find(), moab::TypeSequenceManager::SequenceDataPtr::firstSequence, lastReferenced, lower_bound(), moab::SequenceData::seqManData, sequenceSet, moab::EntitySequence::start_handle(), and moab::SequenceData::start_handle().

Referenced by erase(), insert_sequence(), and split_sequence().

◆ check_valid_handles()

ErrorCode moab::TypeSequenceManager::check_valid_handles ( Error error_handler,
EntityHandle  first,
EntityHandle  last 
) const

Definition at line 602 of file TypeSequenceManager.cpp.

605 {
607  if( i == end() || ( *i )->start_handle() > first )
608  {
609 #if 0
610  // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call
611  // MB_SET_ERR on it
612  fprintf(
613  stderr,
614  "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)first
615  );
616 #endif
617  return MB_ENTITY_NOT_FOUND;
618  }
619 
620  while( ( *i )->end_handle() < last )
621  {
622  EntityHandle prev_end = ( *i )->end_handle();
623  ++i;
624  if( i == end() || prev_end + 1 != ( *i )->start_handle() ) return MB_ENTITY_NOT_FOUND;
625  }
626 
627  return MB_SUCCESS;
628 }

References end(), moab::GeomUtil::first(), lower_bound(), MB_ENTITY_NOT_FOUND, and MB_SUCCESS.

Referenced by moab::SequenceManager::check_valid_entities(), and erase().

◆ empty()

bool moab::TypeSequenceManager::empty ( ) const
inline

Test if this instance contains no sequences.

Definition at line 231 of file TypeSequenceManager.hpp.

232  {
233  return 0 == lastReferenced;
234  }

References lastReferenced.

Referenced by check_valid_data(), get_memory_use(), is_free_sequence(), moab::operator<<(), and moab::Core::print_database().

◆ end() [1/2]

iterator moab::TypeSequenceManager::end ( )
inline

Definition at line 166 of file TypeSequenceManager.hpp.

167  {
168  return sequenceSet.end();
169  }

References sequenceSet.

◆ end() [2/2]

◆ erase() [1/3]

ErrorCode moab::TypeSequenceManager::erase ( Error error_handler,
EntityHandle  entity 
)

Definition at line 630 of file TypeSequenceManager.cpp.

631 {
632  EntitySequence* seq = find( h );
633  if( !seq )
634  {
635 #if 0
636  // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call
637  // MB_SET_ERR on it
638  fprintf(
639  stderr,
640  "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)h
641  );
642 #endif
643  return MB_ENTITY_NOT_FOUND;
644  }
645 
646  if( seq->start_handle() == h )
647  {
648  if( seq->end_handle() != h )
649  {
650  if( seq->using_entire_data() ) availableList.insert( seq->data() );
651  seq->pop_front( 1 );
652  return MB_SUCCESS;
653  }
654  SequenceData* data = seq->data();
655  bool delete_data;
656  ErrorCode rval = remove_sequence( seq, delete_data );
657  if( MB_SUCCESS != rval ) return rval;
658  delete seq;
659  if( delete_data ) delete data;
660  }
661  else if( seq->end_handle() == h )
662  {
663  if( seq->using_entire_data() ) availableList.insert( seq->data() );
664  seq->pop_back( 1 );
665  }
666  else
667  {
668  iterator i = lower_bound( h );
669  if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
670  i = split_sequence( i, h );
671  seq = *i;
672  assert( seq->start_handle() == h );
673  seq->pop_front( 1 );
674  }
675 
676  return MB_SUCCESS;
677 }

References availableList, moab::EntitySequence::data(), moab::EntitySequence::end_handle(), ErrorCode, find(), lower_bound(), MB_ENTITY_NOT_FOUND, MB_SUCCESS, moab::EntitySequence::pop_back(), moab::EntitySequence::pop_front(), remove_sequence(), split_sequence(), moab::EntitySequence::start_handle(), and moab::EntitySequence::using_entire_data().

◆ erase() [2/3]

ErrorCode moab::TypeSequenceManager::erase ( Error error_handler,
EntityHandle  first,
EntityHandle  last 
)

Remove entities.

Update EntitySequence data as necessary to "delete" the specified entities (e.g. split sequences, delete sequences, free SequenceData instances, etc.)

Definition at line 679 of file TypeSequenceManager.cpp.

680 {
681  // First check that all entities in range are valid
682 
683  ErrorCode rval = check_valid_handles( NULL, first, last );
684  if( MB_SUCCESS != rval ) return rval;
685 
686  // Now remove entities
687 
688  // Get first sequence intersecting range
689  iterator i = lower_bound( first );
690  if( i == end() ) // Shouldn't be possible given check_valid_handles call above.
691  return MB_ENTITY_NOT_FOUND;
692 
693  // If range is entirely in interior of sequence, need to split sequence.
694  if( ( *i )->start_handle() < first && ( *i )->end_handle() > last )
695  {
696  if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
697  i = split_sequence( i, first );
698  ( *i )->pop_front( last - first + 1 );
699  assert( check_valid_data( *i ) );
700  return MB_SUCCESS;
701  }
702 
703  // If range doesn't entirely contain first sequence, remove some
704  // handles from the end of the sequence and advance to the next
705  // sequence.
706  if( ( *i )->start_handle() < first )
707  {
708  if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
709  ( *i )->pop_back( ( *i )->end_handle() - first + 1 );
710  ++i;
711  }
712 
713  // Destroy all sequences contained entirely within the range
714  while( i != end() && ( *i )->end_handle() <= last )
715  i = erase( i );
716 
717  // If necessary, remove entities from the beginning of the
718  // last sequence.
719  if( i != end() && ( *i )->start_handle() <= last )
720  {
721  if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
722  ( *i )->pop_front( last - ( *i )->start_handle() + 1 );
723  assert( check_valid_data( *i ) );
724  }
725 
726  return MB_SUCCESS;
727 }

References availableList, check_valid_data(), check_valid_handles(), end(), erase(), ErrorCode, moab::GeomUtil::first(), lower_bound(), MB_ENTITY_NOT_FOUND, MB_SUCCESS, and split_sequence().

◆ erase() [3/3]

TypeSequenceManager::iterator moab::TypeSequenceManager::erase ( iterator  i)
private

Remove a sequence.

Definition at line 259 of file TypeSequenceManager.cpp.

260 {
261  EntitySequence* seq = *i;
262  SequenceData* data = seq->data();
263  iterator j;
264 
265  // Check if we need to delete the referenced SequenceData also
266  bool delete_data;
267  if( seq->using_entire_data() ) // Only sequence
268  delete_data = true;
269  else if( data->seqManData.firstSequence != i )
270  { // Earlier sequence?
271  delete_data = false;
272  availableList.insert( data );
273  }
274  else
275  { // Later sequence ?
276  j = i;
277  ++j;
278  delete_data = ( j == end() || ( *j )->data() != data );
279  if( delete_data )
280  availableList.erase( data );
281  else
282  {
283  availableList.insert( data );
284  data->seqManData.firstSequence = j;
285  }
286  }
287 
288  // Remove sequence, updating i to be next sequence
289  j = i++;
290  sequenceSet.erase( j );
291 
292  // Make sure lastReferenced isn't stale. It can only be NULL if
293  // no sequences.
294  if( lastReferenced == seq ) lastReferenced = sequenceSet.empty() ? 0 : *sequenceSet.begin();
295 
296  // Always delete sequence before the SequenceData it references.
297  assert( 0 == find( seq->start_handle() ) );
298  delete seq;
299  if( delete_data )
300  delete data;
301  else
302  {
303  assert( check_valid_data( *data->seqManData.firstSequence ) );
304  assert( lastReferenced != seq );
305  }
306  return i;
307 }

References availableList, check_valid_data(), moab::EntitySequence::data(), end(), find(), moab::TypeSequenceManager::SequenceDataPtr::firstSequence, lastReferenced, moab::SequenceData::seqManData, sequenceSet, moab::EntitySequence::start_handle(), and moab::EntitySequence::using_entire_data().

Referenced by moab::SequenceManager::delete_entities(), moab::SequenceManager::delete_entity(), and erase().

◆ find() [1/4]

EntitySequence * moab::TypeSequenceManager::find ( EntityHandle  h)
inline

Definition at line 389 of file TypeSequenceManager.hpp.

390 {
391  if( !lastReferenced ) // only null if empty
392  return 0;
393  else if( h >= lastReferenced->start_handle() && h <= lastReferenced->end_handle() )
394  return lastReferenced;
395  else
396  {
397  DummySequence seq( h );
398  iterator i = sequenceSet.find( &seq );
399  return i == end() ? 0 : ( lastReferenced = *i );
400  }
401 }

References end(), lastReferenced, sequenceSet, and moab::EntitySequence::start_handle().

◆ find() [2/4]

EntitySequence * moab::TypeSequenceManager::find ( EntityHandle  h) const
inline

Get EntitySequence for handle.

Returns
EntitySequence for handle, or NULL if no such sequence.

Definition at line 376 of file TypeSequenceManager.hpp.

377 {
378  if( !lastReferenced ) // only null if empty
379  return 0;
380  else if( h >= lastReferenced->start_handle() && h <= lastReferenced->end_handle() )
381  return lastReferenced;
382  else
383  {
384  DummySequence seq( h );
385  const_iterator i = sequenceSet.find( &seq );
386  return i == end() ? 0 : ( lastReferenced = *i );
387  }
388 }

References end(), lastReferenced, sequenceSet, and moab::EntitySequence::start_handle().

Referenced by check_valid_data(), erase(), and moab::SequenceManager::find().

◆ find() [3/4]

ErrorCode moab::TypeSequenceManager::find ( EntityHandle  h,
const EntitySequence *&  seq 
) const
inline

Definition at line 403 of file TypeSequenceManager.hpp.

404 {
405  if( !lastReferenced )
406  { // only null if empty
407  seq = 0;
408  return MB_ENTITY_NOT_FOUND;
409  }
410 
411  seq = lastReferenced;
412  if( h >= seq->start_handle() && h <= seq->end_handle() )
413  {
414  return MB_SUCCESS;
415  }
416 
417  DummySequence ds( h );
418  iterator i = sequenceSet.lower_bound( &ds );
419  if( i == end() || ( *i )->start_handle() > h )
420  {
421  seq = 0;
422  return MB_ENTITY_NOT_FOUND;
423  }
424  seq = *i;
425  lastReferenced = *i;
426  return MB_SUCCESS;
427 }

References end(), lastReferenced, MB_ENTITY_NOT_FOUND, MB_SUCCESS, sequenceSet, and moab::EntitySequence::start_handle().

◆ find() [4/4]

ErrorCode moab::TypeSequenceManager::find ( EntityHandle  h,
EntitySequence *&  seq 
)
inline

Definition at line 429 of file TypeSequenceManager.hpp.

430 {
431  if( !lastReferenced )
432  { // only null if empty
433  seq = 0;
434  return MB_ENTITY_NOT_FOUND;
435  }
436 
437  seq = lastReferenced;
438  if( h >= seq->start_handle() && h <= seq->end_handle() )
439  {
440  return MB_SUCCESS;
441  }
442 
443  DummySequence ds( h );
444  iterator i = sequenceSet.lower_bound( &ds );
445  if( i == end() || ( *i )->start_handle() > h )
446  {
447  seq = 0;
448  return MB_ENTITY_NOT_FOUND;
449  }
450  seq = *i;
451  lastReferenced = *i;
452  return MB_SUCCESS;
453 }

References end(), lastReferenced, MB_ENTITY_NOT_FOUND, MB_SUCCESS, sequenceSet, and moab::EntitySequence::start_handle().

◆ find_free_block()

EntityHandle moab::TypeSequenceManager::find_free_block ( EntityID  num_entities,
EntityHandle  min_start_handle,
EntityHandle  max_end_handle 
)

Find block of free handles.

Find block of free handles, such that block does not overlap any existing EntitySequence.

Returns
First handle of block, or zero if no block found.

Definition at line 423 of file TypeSequenceManager.cpp.

426 {
427  const_iterator i = lower_bound( min_start_handle );
428  if( i == end() ) return min_start_handle;
429 
430  if( ( *i )->start_handle() < min_start_handle + num_entities ) return min_start_handle;
431 
432  EntityHandle prev_end = ( *i )->end_handle();
433  ++i;
434  for( ; i != end(); prev_end = ( *i )->end_handle(), ++i )
435  {
436  EntityID len = ( *i )->start_handle() - prev_end - 1;
437  if( len >= num_entities ) break;
438  }
439 
440  if( prev_end + num_entities > max_end_handle )
441  return 0;
442  else
443  return prev_end + 1;
444 }

References end(), and lower_bound().

◆ find_free_handle()

TypeSequenceManager::iterator moab::TypeSequenceManager::find_free_handle ( EntityHandle  min_start_handle,
EntityHandle  max_end_handle,
bool &  append_out,
int  values_per_ent = 0 
)

Allocate a handle in an existing entity sequence.

Find an existing entity sequence to which a new handle can be prepended or appended. The 'append_out' flag indicates to the caller that the new handle should be appended to the returned sequence if true, and prepended if false.

If no appropriate EntitySequence is available, NULL will be returned. The caller will typically then want to use find_free_sequence() to find appropriate values for the creation of a new EntitySequence.

Definition at line 334 of file TypeSequenceManager.cpp.

338 {
339  for( data_iterator i = availableList.begin(); i != availableList.end(); ++i )
340  {
341  if( ( *( *i )->seqManData.firstSequence )->values_per_entity() != values_per_ent ) continue;
342 
343  if( ( *i )->start_handle() > max_end_handle || ( *i )->end_handle() < min_start_handle ) continue;
344 
345  for( iterator j = ( *i )->seqManData.firstSequence;
346  j != end() && ( *j )->start_handle() <= ( max_end_handle + 1 ) && ( *j )->data() == *i; ++j )
347  {
348  if( ( *j )->end_handle() + 1 < min_start_handle ) continue;
349  if( ( *j )->start_handle() > ( *i )->start_handle() && ( *j )->start_handle() > min_start_handle )
350  {
351  append_out = false;
352  return j;
353  }
354  if( ( *j )->end_handle() < ( *i )->end_handle() && ( *j )->end_handle() < max_end_handle )
355  {
356  append_out = true;
357  return j;
358  }
359  }
360  }
361 
362  return end();
363 }

References availableList, and end().

Referenced by moab::SequenceManager::create_element(), moab::SequenceManager::create_mesh_set(), and moab::SequenceManager::create_vertex().

◆ find_free_sequence()

EntityHandle moab::TypeSequenceManager::find_free_sequence ( EntityID  num_entities,
EntityHandle  min_start_handle,
EntityHandle  max_end_handle,
SequenceData *&  sequence_data_out,
EntityID sequence_data_size,
int  values_per_ent = 0 
)

Find block of free handles.

Find block of free handles, such that block a) does not overlap any existing EntitySequence and b) is either entirely within one existing SequenceData or does not overlap any SequenceData.

Parameters
num_entitiesSize of handle block.
min_start_handleBlock may not contain any handle less than this.
max_end_handleBlock may not contain any handle greater than this.
sequence_data_outIf block is within an unused portion of an existing SequenceData, a pointer to that SequenceData. NULL otherwise.
Returns
values_per_ent Matched against EntitySequence::values_per_entity. An existing SequenceData will not be returned if the existing EntitySequences using have a different value than the passed one.

Definition at line 467 of file TypeSequenceManager.cpp.

473 {
474  if( max_end_handle < min_start_handle + num_entities - 1 ) return 0;
475 
476  EntityHandle result;
477  iterator p, i = lower_bound( min_start_handle );
478  range_data d = { num_entities, min_start_handle, max_end_handle, 0, 0 };
479 
480  if( i == end() )
481  {
482  data_out = 0;
483  return min_start_handle;
484  }
485  else if( i == begin() )
486  {
487  if( ( *i )->values_per_entity() == num_verts )
488  {
489  d.first = ( *i )->data()->start_handle();
490  d.last = ( *i )->start_handle() - 1;
491  if( check_range( d, true, result ) )
492  {
493  data_out = ( *i )->data();
494  return result;
495  }
496  }
497  d.first = min_start_handle;
498  d.last = ( *i )->data()->start_handle() - 1;
499  if( check_range( d, true, result ) )
500  {
501  data_out = 0;
502  // This will back up against the end of the seq data, so
503  // size the data that way
504  data_size = num_entities;
505  return result;
506  }
507  p = i++;
508  }
509  else
510  {
511  p = i;
512  --p;
513  }
514 
515  for( ; i != end() && ( *i )->start_handle() < max_end_handle; p = i++ )
516  {
517  if( ( *p )->data() == ( *i )->data() )
518  {
519  if( ( *p )->values_per_entity() == num_verts )
520  {
521  d.first = ( *p )->end_handle() + 1;
522  d.last = ( *i )->start_handle() - 1;
523  if( check_range( d, false, result ) )
524  {
525  data_out = ( *p )->data();
526  return result;
527  }
528  }
529  }
530  else
531  {
532  if( ( *p )->values_per_entity() == num_verts )
533  {
534  d.first = ( *p )->end_handle() + 1;
535  d.last = ( *p )->data()->end_handle();
536  if( check_range( d, false, result ) )
537  {
538  data_out = ( *p )->data();
539  return result;
540  }
541  }
542  if( ( *i )->values_per_entity() == num_verts )
543  {
544  d.first = ( *i )->data()->start_handle();
545  d.last = ( *i )->start_handle() - 1;
546  if( check_range( d, true, result ) )
547  {
548  data_out = ( *i )->data();
549  return result;
550  }
551  }
552  d.first = ( *p )->data()->end_handle() + 1;
553  d.last = ( *i )->data()->start_handle() - 1;
554  if( check_range( d, false, result ) )
555  {
556  data_out = 0;
557  data_size = d.last - d.first + 1;
558  return result;
559  }
560  }
561  }
562 
563  if( ( *p )->values_per_entity() == num_verts )
564  {
565  d.first = ( *p )->end_handle() + 1;
566  d.last = ( *p )->data()->end_handle();
567  if( check_range( d, false, result ) )
568  {
569  data_out = ( *p )->data();
570  return result;
571  }
572  }
573 
574  d.first = ( *p )->data()->end_handle() + 1;
575  d.last = max_end_handle;
576  if( check_range( d, false, result ) )
577  {
578  data_out = 0;
579  return result;
580  }
581 
582  data_out = 0;
583  return 0;
584 }

References begin(), moab::check_range(), end(), moab::range_data::first, moab::range_data::last, and lower_bound().

Referenced by moab::SequenceManager::create_element(), moab::SequenceManager::create_mesh_set(), moab::SequenceManager::create_vertex(), and moab::SequenceManager::sequence_start_handle().

◆ get_entities() [1/2]

void moab::TypeSequenceManager::get_entities ( Range entities_out) const
inline

Get handles for all entities in all sequences.

Definition at line 460 of file TypeSequenceManager.hpp.

461 {
462  Range::iterator in = entities_out.begin();
463  for( const_iterator i = begin(); i != end(); ++i )
464  in = entities_out.insert( in, ( *i )->start_handle(), ( *i )->end_handle() );
465 }

References moab::Range::begin(), begin(), end(), and moab::Range::insert().

Referenced by moab::SequenceManager::get_entities().

◆ get_entities() [2/2]

void moab::TypeSequenceManager::get_entities ( std::vector< EntityHandle > &  entities_out) const
inline

Get handles for all entities in all sequences.

Definition at line 467 of file TypeSequenceManager.hpp.

468 {
469  for( const_iterator i = begin(); i != end(); ++i )
470  for( EntityHandle j = ( *i )->start_handle(); j <= ( *i )->end_handle(); ++j )
471  entities_out.push_back( j );
472 }

References begin(), and end().

◆ get_last_accessed()

const EntitySequence * moab::TypeSequenceManager::get_last_accessed ( ) const
inline

Definition at line 455 of file TypeSequenceManager.hpp.

456 {
457  return lastReferenced; /* only NULL if TypeSequenceManager is empty */
458 }

References lastReferenced.

Referenced by moab::SequenceManager::get_last_accessed_sequence().

◆ get_memory_use() [1/2]

void moab::TypeSequenceManager::get_memory_use ( EntityHandle  start,
EntityHandle  end,
unsigned long long &  total_entity_storage,
unsigned long long &  total_amortized_storage 
) const

Definition at line 895 of file TypeSequenceManager.cpp.

899 {
900  entity_storage = total_storage = 0;
901 
902  while( first <= last )
903  {
905  if( i == end() ) return;
906 
907  SequenceData* data = ( *i )->data();
908  if( first < data->end_handle() )
909  {
910  append_memory_use( first, last, data, entity_storage, total_storage );
911  }
912  first = data->end_handle() + 1;
913  }
914 }

References append_memory_use(), end(), moab::SequenceData::end_handle(), moab::GeomUtil::first(), and lower_bound().

◆ get_memory_use() [2/2]

void moab::TypeSequenceManager::get_memory_use ( unsigned long long &  total_entity_storage,
unsigned long long &  total_storage 
) const

Definition at line 841 of file TypeSequenceManager.cpp.

842 {
843  entity_storage = total_storage = 0;
844  if( empty() ) return;
845 
846  EntityType mytype = TYPE_FROM_HANDLE( lastReferenced->start_handle() );
847  int junk;
848  get_memory_use( CREATE_HANDLE( mytype, MB_START_ID, junk ), CREATE_HANDLE( mytype, MB_END_ID, junk ),
849  entity_storage, total_storage );
850 }

References moab::CREATE_HANDLE(), empty(), lastReferenced, MB_END_ID, MB_START_ID, moab::EntitySequence::start_handle(), and moab::TYPE_FROM_HANDLE().

Referenced by moab::SequenceManager::get_memory_use().

◆ get_number_entities()

EntityID moab::TypeSequenceManager::get_number_entities ( ) const
inline

Get number of entities represented by all sequences.

Definition at line 474 of file TypeSequenceManager.hpp.

475 {
476  EntityID count = 0;
477  for( const_iterator i = begin(); i != end(); ++i )
478  count += ( *i )->size();
479  return count;
480 }

References begin(), and end().

Referenced by moab::SequenceManager::get_number_entities().

◆ get_occupied_size()

EntityID moab::TypeSequenceManager::get_occupied_size ( const SequenceData data) const

Get used size of SequenceData.

Get the sum of the size of all EntitySequences referencing a SequenceData. Used for memory use calculations.

Definition at line 916 of file TypeSequenceManager.cpp.

917 {
918  EntityID result = 0;
919  for( const_iterator i = data->seqManData.firstSequence; i != end() && ( *i )->data() == data; ++i )
920  result += ( *i )->size();
921 
922  return result;
923 }

References end(), moab::TypeSequenceManager::SequenceDataPtr::firstSequence, and moab::SequenceData::seqManData.

Referenced by moab::AEntityFactory::get_memory_use().

◆ get_sequence_count()

unsigned long moab::TypeSequenceManager::get_sequence_count ( ) const
inline

Definition at line 363 of file TypeSequenceManager.hpp.

364  {
365  return sequenceSet.size();
366  }

References sequenceSet.

◆ insert_sequence()

ErrorCode moab::TypeSequenceManager::insert_sequence ( EntitySequence seq_ptr)

Add an entity sequence.

Take ownership of passed EntitySequence, and update relevant data structures. Sequence may not overlap with any existing sequence.

NOTE: Sequence may be merged with other, existing sequences. This function will always ensure that the passed EntitySequence* is the remaining one, but the passed sequence may have modified start and end handles.

Definition at line 90 of file TypeSequenceManager.cpp.

91 {
92  if( !seq_ptr->data() ) return MB_FAILURE;
93 
94  if( seq_ptr->data()->start_handle() > seq_ptr->start_handle() ||
95  seq_ptr->data()->end_handle() < seq_ptr->end_handle() || seq_ptr->end_handle() < seq_ptr->start_handle() )
96  return MB_FAILURE;
97 
98  iterator i = lower_bound( seq_ptr->start_handle() );
99  if( i != end() )
100  {
101  if( ( *i )->start_handle() <= seq_ptr->end_handle() ) return MB_ALREADY_ALLOCATED;
102  if( seq_ptr->data() != ( *i )->data() && ( *i )->data()->start_handle() <= seq_ptr->data()->end_handle() )
103  return MB_ALREADY_ALLOCATED;
104  }
105 
106  if( i != begin() )
107  {
108  iterator j = i;
109  --j;
110  if( seq_ptr->data() != ( *j )->data() && ( *j )->data()->end_handle() >= seq_ptr->data()->start_handle() )
111  return MB_ALREADY_ALLOCATED;
112  }
113 
114  i = sequenceSet.insert( i, seq_ptr );
115 
116  // Merge with previous sequence ?
117  if( seq_ptr->start_handle() > seq_ptr->data()->start_handle() && i != begin() )
118  {
119  if( MB_SUCCESS != check_merge_prev( i ) )
120  {
121  sequenceSet.erase( i );
122  return MB_FAILURE;
123  }
124  }
125 
126  // Merge with next sequence ?
127  if( ( *i )->end_handle() < ( *i )->data()->end_handle() )
128  {
129  if( MB_SUCCESS != check_merge_next( i ) )
130  {
131  sequenceSet.erase( i );
132  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  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  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  if( ( *i )->start_handle() == ( *i )->data()->start_handle() || lower_bound( ( *i )->data()->start_handle() ) == i )
149  ( *i )->data()->seqManData.firstSequence = i;
150 
151  assert( check_valid_data( seq_ptr ) );
152  return MB_SUCCESS;
153 }

References availableList, begin(), check_merge_next(), check_merge_prev(), check_valid_data(), moab::EntitySequence::data(), end(), moab::EntitySequence::end_handle(), moab::SequenceData::end_handle(), moab::TypeSequenceManager::SequenceDataPtr::firstSequence, lastReferenced, lower_bound(), MB_ALREADY_ALLOCATED, MB_SUCCESS, moab::SequenceData::seqManData, sequenceSet, moab::EntitySequence::start_handle(), moab::SequenceData::start_handle(), and moab::EntitySequence::using_entire_data().

Referenced by moab::SequenceManager::allocate_mesh_set(), moab::SequenceManager::create_element(), moab::SequenceManager::create_entity_sequence(), moab::SequenceManager::create_mesh_set(), moab::SequenceManager::create_meshset_sequence(), moab::SequenceManager::create_scd_sequence(), moab::SequenceManager::create_sweep_sequence(), moab::SequenceManager::create_vertex(), and replace_subsequence().

◆ is_free_handle()

ErrorCode moab::TypeSequenceManager::is_free_handle ( EntityHandle  handle,
iterator seq_ptr_out,
SequenceData *&  data_ptr_out,
EntityHandle block_start,
EntityHandle block_end,
int  values_per_ent = 0 
)

Check if specific handle is free for allocation.

Check if a specific handle is not currently allocated and can be allocated with the passed value of values_per_ent. For example, the handle may not be allocated, but it may fall within an existing SequenceData. In that case, it must be possible to store the specified values_per_ent in the existing SequenceData.

There are four possible return 'states' from this function:

  • handle is not available or cannot be allocated with specified values_per_ent. Returned error code is MB_ALREADY_ALLOCATED.
  • handle can be appended or prepended to an existing sequence. seq_ptr_out is set to the sequence the handle should be added to.
  • handle cannot be appended to an existing sequence but falls within an existing SequenceData. The caller is expected to create a new sequence referencing that SequenceData. seq_ptr_out is NULL and data_ptr_out is set to existing SequenceData.
  • handle does not correspond to any existing sequence or data. The caller is expected to create a new sequence and SequenceData. Both seq_ptr_out and data_ptr_out are set to NULL. block_start and block_end are set to start and end handles of the largest sequence that can be allocated and contain the input handle.
Parameters
handleThe handle the caller wishes to allocate as a new entity
seq_ptr_outOutput: pointer to sequence to append or prepend to to allocate handle. end() if no such sequence.
data_ptr_outOutput: Pointer to existing SequenceData containing input handle, or NULL if no such SequenceData.
block_startOutput: Smallest possible start handle for new sequence.
block_endOutput: Largest possible end handle for new sequence.

Definition at line 740 of file TypeSequenceManager.cpp.

746 {
747  int junk;
748  block_start = CREATE_HANDLE( TYPE_FROM_HANDLE( handle ), MB_START_ID, junk );
749  block_end = CREATE_HANDLE( TYPE_FROM_HANDLE( handle ), MB_END_ID, junk );
750 
751  iterator i = lower_bound( handle );
752  if( i != end() )
753  {
754  block_end = ( *i )->start_handle() - 1;
755 
756  // If sequence contains handle, then already allocated
757  if( ( *i )->start_handle() <= handle ) return MB_ALREADY_ALLOCATED;
758 
759  // Handle is not within an existing sequence, but is
760  // within an existing SequenceData...
761  if( ( *i )->data()->start_handle() <= handle )
762  {
763  // If values_per_entity don't match, can't put new entity
764  // in existing SequenceData
765  if( ( *i )->values_per_entity() != values_per_ent ) return MB_ALREADY_ALLOCATED;
766 
767  data_ptr_out = ( *i )->data();
768  if( block_end == handle )
769  {
770  // Prepend to existing sequence
771  seq_iter_out = i;
772  block_start = handle;
773  }
774  else
775  {
776  // Add new sequence to existing SequenceData
777  seq_iter_out = end();
778  if( i == begin() || ( *--i )->data() != data_ptr_out )
779  block_start = data_ptr_out->start_handle();
780  else
781  block_start = ( *i )->end_handle() + 1;
782  }
783  return MB_SUCCESS;
784  }
785  }
786 
787  if( i != begin() )
788  {
789  --i;
790  block_start = ( *i )->end_handle() + 1;
791 
792  // Handle is within previous sequence data...
793  if( ( *i )->data()->end_handle() >= handle )
794  {
795  // If values_per_entity don't match, can't put new entity
796  // in existing SequenceData
797  if( ( *i )->values_per_entity() != values_per_ent ) return MB_ALREADY_ALLOCATED;
798 
799  data_ptr_out = ( *i )->data();
800  if( block_start == handle )
801  {
802  // Append to existing sequence
803  seq_iter_out = i;
804  block_end = handle;
805  }
806  else
807  {
808  // Add new sequence to existing SequenceData
809  seq_iter_out = end();
810  if( ++i == end() || ( *i )->data() != data_ptr_out )
811  block_end = data_ptr_out->end_handle();
812  else
813  block_end = ( *i )->start_handle() - 1;
814  }
815  return MB_SUCCESS;
816  }
817  }
818 
819  seq_iter_out = end();
820  data_ptr_out = 0;
821 
822  return MB_SUCCESS;
823 }

References begin(), moab::CREATE_HANDLE(), end(), moab::SequenceData::end_handle(), lower_bound(), MB_ALREADY_ALLOCATED, MB_END_ID, MB_START_ID, MB_SUCCESS, moab::SequenceData::start_handle(), and moab::TYPE_FROM_HANDLE().

Referenced by moab::SequenceManager::allocate_mesh_set().

◆ is_free_sequence()

bool moab::TypeSequenceManager::is_free_sequence ( EntityHandle  start_handle,
EntityID  num_entities,
SequenceData *&  sequence_data_out,
int  values_per_ent = 0 
)

Check if block of handles is free.

Check if block of handles is free and can be allocated as a single EntitySequence. If the block of handles is contained within an unused portion of a SequenceData, the SequenceData is returned.

Definition at line 365 of file TypeSequenceManager.cpp.

369 {
370  data_out = 0;
371  if( empty() ) return true;
372 
373  const_iterator i = lower_bound( start );
374  if( i == end() )
375  {
376  --i; // Safe because already tested empty()
377  // If we don't overlap the last data object...
378  if( ( *i )->data()->end_handle() < start ) return true;
379  data_out = ( *i )->data();
380  if( ( *i )->values_per_entity() != values_per_ent ) return false;
381  // If we overlap a data object, we must be entirely inside of it
382  return start + num_entities - 1 <= ( *i )->data()->end_handle();
383  }
384 
385 #ifndef NDEBUG
386  if( i != begin() )
387  {
388  const_iterator j = i;
389  --j;
390  assert( ( *j )->end_handle() < start );
391  }
392 #endif
393 
394  // Check if we fit in the block of free handles
395  if( start + num_entities > ( *i )->start_handle() ) // start + num + 1 >= i->start
396  return false;
397 
398  // Check if we overlap the data for the next sequence
399  if( start + num_entities > ( *i )->data()->start_handle() )
400  {
401  data_out = ( *i )->data();
402  if( ( *i )->values_per_entity() != values_per_ent ) return false;
403  // If overlap, must be entirely contained
404  return start >= data_out->start_handle() && start + num_entities - 1 <= data_out->end_handle();
405  }
406 
407  // Check if we overlap the data for the previous sequence
408  if( i != begin() )
409  {
410  --i;
411  if( ( *i )->data()->end_handle() >= start )
412  {
413  data_out = ( *i )->data();
414  if( ( *i )->values_per_entity() != values_per_ent ) return false;
415  return start + num_entities - 1 <= ( *i )->data()->end_handle();
416  }
417  }
418 
419  // Unused handle block that overlaps no SequenceData
420  return true;
421 }

References begin(), empty(), end(), moab::SequenceData::end_handle(), lower_bound(), and moab::SequenceData::start_handle().

Referenced by moab::SequenceManager::sequence_start_handle().

◆ last_free_handle()

EntityHandle moab::TypeSequenceManager::last_free_handle ( EntityHandle  after_this) const

Definition at line 586 of file TypeSequenceManager.cpp.

587 {
588  int junk;
589  const_iterator it = lower_bound( after_this );
590  if( it == end() )
591  return CREATE_HANDLE( TYPE_FROM_HANDLE( after_this ), MB_END_ID, junk );
592  else if( ( *it )->start_handle() > after_this )
593  {
594  // Need to check against the sequence data first
595  EntityHandle rhandle = ( *it )->data()->start_handle();
596  return rhandle - 1;
597  }
598  else
599  return 0;
600 }

References moab::CREATE_HANDLE(), end(), lower_bound(), MB_END_ID, and moab::TYPE_FROM_HANDLE().

Referenced by moab::SequenceManager::new_sequence_size().

◆ lower_bound() [1/2]

iterator moab::TypeSequenceManager::lower_bound ( EntityHandle  h)
inline

Definition at line 182 of file TypeSequenceManager.hpp.

183  {
184  DummySequence f( h );
185  return sequenceSet.lower_bound( &f );
186  }

References sequenceSet.

◆ lower_bound() [2/2]

const_iterator moab::TypeSequenceManager::lower_bound ( EntityHandle  h) const
inline

Return EntitySequence for specified handle.

Return EntitySequence for specified handle, or if no such sequence, the next one. Returns end() if all sequences have ranges less than specified handle.

Definition at line 177 of file TypeSequenceManager.hpp.

178  {
179  DummySequence f( h );
180  return sequenceSet.lower_bound( &f );
181  }

References sequenceSet.

Referenced by check_valid_data(), check_valid_handles(), erase(), find_free_block(), find_free_sequence(), moab::Core::get_coords(), get_memory_use(), insert_sequence(), is_free_handle(), is_free_sequence(), last_free_handle(), remove_sequence(), and replace_subsequence().

◆ merge_internal()

ErrorCode moab::TypeSequenceManager::merge_internal ( iterator  keep,
iterator  dead 
)
private

Definition at line 46 of file TypeSequenceManager.cpp.

47 {
48  EntitySequence* dead = *j;
49  sequenceSet.erase( j );
50  ErrorCode rval = ( *i )->merge( *dead );
51  if( MB_SUCCESS != rval )
52  {
53  sequenceSet.insert( dead );
54  return rval;
55  }
56 
57  if( lastReferenced == dead ) lastReferenced = *i;
58  delete dead;
59 
60  // If merging results in no unused portions of the SequenceData,
61  // remove it from the available list.
62  if( ( *i )->using_entire_data() ) availableList.erase( ( *i )->data() );
63 
64  return MB_SUCCESS;
65 }

References availableList, ErrorCode, lastReferenced, MB_SUCCESS, and sequenceSet.

Referenced by check_merge_next(), and check_merge_prev().

◆ notify_appended()

ErrorCode moab::TypeSequenceManager::notify_appended ( iterator  seq)

Notify that sequence was appended to.

Notify of sequence modifications so we can check if sequence needs to be merged.

Definition at line 825 of file TypeSequenceManager.cpp.

826 {
827  ErrorCode rval = check_merge_next( seq );
828  if( ( *seq )->using_entire_data() ) availableList.erase( ( *seq )->data() );
829 
830  return rval;
831 }

References availableList, check_merge_next(), and ErrorCode.

Referenced by moab::SequenceManager::allocate_mesh_set(), moab::SequenceManager::create_element(), moab::SequenceManager::create_mesh_set(), and moab::SequenceManager::create_vertex().

◆ notify_prepended()

ErrorCode moab::TypeSequenceManager::notify_prepended ( iterator  seq)

Notify that sequence was prepended to.

Notify of sequence modifications so we can check if sequence needs to be merged.

Definition at line 833 of file TypeSequenceManager.cpp.

834 {
835  ErrorCode rval = check_merge_prev( seq );
836  if( ( *seq )->using_entire_data() ) availableList.erase( ( *seq )->data() );
837 
838  return rval;
839 }

References availableList, check_merge_prev(), and ErrorCode.

Referenced by moab::SequenceManager::allocate_mesh_set(), moab::SequenceManager::create_element(), moab::SequenceManager::create_mesh_set(), and moab::SequenceManager::create_vertex().

◆ remove_sequence()

ErrorCode moab::TypeSequenceManager::remove_sequence ( const EntitySequence seq_ptr,
bool &  is_last_user_of_sequence_data 
)

Remove an entity sequence.

Give up ownership of specified EntitySequence, and remove it from all internal data structures. Passes back bool flag to notify caller that ownership of the corresponding SequenceData is also relinquished because the specified EntitySequence is the last one referencing it.

Definition at line 309 of file TypeSequenceManager.cpp.

310 {
311  // Remove sequence from set
312  iterator i = lower_bound( seq_ptr->start_handle() );
313  if( i == end() || *i != seq_ptr ) return MB_ENTITY_NOT_FOUND;
314  sequenceSet.erase( i );
315 
316  // Check if this is the only sequence referencing its data
317  if( seq_ptr->using_entire_data() )
318  unreferenced_data = true;
319  else
320  {
321  i = lower_bound( seq_ptr->data()->start_handle() );
322  unreferenced_data = i == end() || ( *i )->data() != seq_ptr->data();
323  if( unreferenced_data )
324  availableList.erase( seq_ptr->data() );
325  else
326  seq_ptr->data()->seqManData.firstSequence = i; // Might be 'i' already
327  }
328 
329  if( lastReferenced == seq_ptr ) lastReferenced = sequenceSet.empty() ? 0 : *sequenceSet.begin();
330 
331  return MB_SUCCESS;
332 }

References availableList, moab::EntitySequence::data(), end(), moab::TypeSequenceManager::SequenceDataPtr::firstSequence, lastReferenced, lower_bound(), MB_ENTITY_NOT_FOUND, MB_SUCCESS, moab::SequenceData::seqManData, sequenceSet, moab::EntitySequence::start_handle(), moab::SequenceData::start_handle(), and moab::EntitySequence::using_entire_data().

Referenced by erase().

◆ replace_subsequence()

ErrorCode moab::TypeSequenceManager::replace_subsequence ( EntitySequence seq_ptr,
const int *  tag_sizes,
int  num_tag_sizes 
)

Replace sequence or subset of sequence.

Replace one sequence or a subset of one sequence with another sequence. With fail if a) the existing sequence is not a subset of an existing sequence or b) existing sequence shares a SequenceData with the passed sequence.

This method is provided for use when changing the number of nodes in elements.

Definition at line 155 of file TypeSequenceManager.cpp.

156 {
157  // Find the sequence of interest
158  iterator i = lower_bound( seq_ptr->start_handle() );
159  if( i == end() || ( *i )->data() == seq_ptr->data() ) return MB_FAILURE;
160  // New sequence must be a subset of an existing one
161  if( seq_ptr->start_handle() < ( *i )->start_handle() || seq_ptr->end_handle() > ( *i )->end_handle() )
162  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  if( !seq_ptr->using_entire_data() ) return MB_FAILURE;
167  // Copy tag data (move ownership of var-len data)
168  SequenceData* const dead_data = ( *i )->data();
169  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  iterator p, n = i;
175  p = ( *i )->data()->seqManData.firstSequence;
176  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  const bool some_before = ( ( *i )->start_handle() < seq_ptr->start_handle() );
192  const bool some_after = ( ( *i )->end_handle() > seq_ptr->end_handle() );
193  // Case 0
194  if( !( some_before || some_after ) )
195  {
196  // Remove dead sequence from internal lists
197  EntitySequence* seq = *i;
198  iterator dead = i;
199  ++i;
200  if( p == dead ) p = i;
201  sequenceSet.erase( dead );
202 
203  // Delete old sequence
204  delete seq;
205  // Make sure lastReferenced isn't stale
206  if( lastReferenced == seq ) lastReferenced = seq_ptr;
207  }
208  // Case 1
209  else if( some_before && some_after )
210  {
211  i = split_sequence( i, seq_ptr->start_handle() );
212  ( *i )->pop_front( seq_ptr->size() );
213  }
214  // Case 2
215  else if( some_after )
216  {
217  ( *i )->pop_front( seq_ptr->size() );
218  }
219  // Case 3
220  else
221  { // some_before
222  ( *i )->pop_back( seq_ptr->size() );
223  ++i;
224  }
225 
226  // Now subdivide the underlying sequence data as necessary
227  availableList.erase( dead_data );
228  if( p != i )
229  {
230  iterator last = i;
231  --last;
232  SequenceData* new_data = ( *p )->create_data_subset( ( *p )->start_handle(), ( *last )->end_handle() );
233  new_data->seqManData.firstSequence = p;
234 
235  for( ; p != i; ++p )
236  ( *p )->data( new_data );
237  // Copy tag data (move ownership of var-len data)
238  dead_data->move_tag_data( new_data, tag_sizes, num_tag_sizes );
239  if( !( *new_data->seqManData.firstSequence )->using_entire_data() ) availableList.insert( new_data );
240  }
241  if( i != n )
242  {
243  iterator last = n;
244  --last;
245  SequenceData* new_data = ( *i )->create_data_subset( ( *i )->start_handle(), ( *last )->end_handle() );
246  new_data->seqManData.firstSequence = i;
247  for( ; i != n; ++i )
248  ( *i )->data( new_data );
249  // Copy tag data (move ownership of var-len data)
250  dead_data->move_tag_data( new_data, tag_sizes, num_tag_sizes );
251  if( !( *new_data->seqManData.firstSequence )->using_entire_data() ) availableList.insert( new_data );
252  }
253  delete dead_data;
254 
255  // Put new sequence in lists
256  return insert_sequence( seq_ptr );
257 }

References availableList, moab::EntitySequence::data(), end(), moab::EntitySequence::end_handle(), moab::TypeSequenceManager::SequenceDataPtr::firstSequence, insert_sequence(), lastReferenced, lower_bound(), moab::SequenceData::move_tag_data(), moab::SequenceData::seqManData, sequenceSet, moab::EntitySequence::size(), split_sequence(), moab::EntitySequence::start_handle(), and moab::EntitySequence::using_entire_data().

Referenced by moab::SequenceManager::replace_subsequence().

◆ split_sequence()

TypeSequenceManager::iterator moab::TypeSequenceManager::split_sequence ( iterator  i,
EntityHandle  h 
)
private

split a sequence

Definition at line 729 of file TypeSequenceManager.cpp.

730 {
731  EntitySequence* seq = ( *i )->split( h );
732  if( !seq ) return end();
733 
734  i = sequenceSet.insert( i, seq );
735  assert( check_valid_data( *i ) );
736 
737  return i;
738 }

References check_valid_data(), end(), sequenceSet, and moab::EntitySequence::split().

Referenced by erase(), and replace_subsequence().

◆ upper_bound()

const_iterator moab::TypeSequenceManager::upper_bound ( EntityHandle  h) const
inline

Return EntitySequence after specified handle.

Return EntitySequence with smallest start handle that is greater than input handle. Returns end() if all sequences have start handles less than specified handle.

Definition at line 195 of file TypeSequenceManager.hpp.

196  {
197  DummySequence f( h );
198  return sequenceSet.upper_bound( &f );
199  }

References sequenceSet.

Referenced by moab::RangeSeqIntersectIter::find_invalid_range().

Member Data Documentation

◆ availableList

data_set_type moab::TypeSequenceManager::availableList
private

◆ lastReferenced

EntitySequence* moab::TypeSequenceManager::lastReferenced
mutableprivate

◆ sequenceSet


The documentation for this class was generated from the following files: