MOAB: Mesh Oriented datABase  (version 5.2.1)
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.
typedef set_type::iterator iterator
 Iterator for set_type.
typedef set_type::const_iterator const_iterator
 Iterator for set_type.
typedef std::set< SequenceData
*, SequenceCompare
< SequenceData > > 
data_set_type
 Type of container for organizing SequenceData instances.
typedef data_set_type::iterator data_iterator
 iterator type for data_set_type

Public Member Functions

ErrorCode insert_sequence (EntitySequence *seq_ptr)
 Add an entity sequence.
ErrorCode remove_sequence (const EntitySequence *seq_ptr, bool &is_last_user_of_sequence_data)
 Remove an entity sequence.
ErrorCode replace_subsequence (EntitySequence *seq_ptr, const int *tag_sizes, int num_tag_sizes)
 Replace sequence or subset of sequence.
 TypeSequenceManager ()
 ~TypeSequenceManager ()
const_iterator begin () const
 Start of EntitySequence set.
iterator begin ()
const_iterator end () const
 End of EntitySequence set.
iterator end ()
const_iterator lower_bound (EntityHandle h) const
 Return EntitySequence for specified handle.
iterator lower_bound (EntityHandle h)
const_iterator upper_bound (EntityHandle h) const
 Return EntitySequence after specified handle.
EntitySequencefind (EntityHandle h) const
 Get EntitySequence for handle.
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.
void get_entities (std::vector< EntityHandle > &entities_out) const
 Get handles for all entities in all sequences.
EntityID get_number_entities () const
 Get number of entities represented by all sequences.
ErrorCode check_valid_handles (Error *error_handler, EntityHandle first, EntityHandle last) const
ErrorCode erase (Error *error_handler, EntityHandle first, EntityHandle last)
 Remove entities.
ErrorCode erase (Error *error_handler, EntityHandle entity)
bool empty () const
 Test if this instance contains no sequences.
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.
EntityHandle find_free_block (EntityID num_entities, EntityHandle min_start_handle, EntityHandle max_end_handle)
 Find block of free handles.
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.
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.
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.
EntityHandle last_free_handle (EntityHandle after_this) const
ErrorCode notify_prepended (iterator seq)
 Notify that sequence was prepended to.
ErrorCode notify_appended (iterator seq)
 Notify that sequence was appended to.
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.

Private Member Functions

iterator erase (iterator i)
 Remove a sequence.
iterator split_sequence (iterator i, EntityHandle h)
 split a sequence
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.
set_type sequenceSet
 Set of all managed EntitySequence instances.
data_set_type availableList
 SequenceData containing unused entries.

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

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

Iterator for set_type.

Definition at line 69 of file TypeSequenceManager.hpp.

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

iterator type for data_set_type

Definition at line 73 of file TypeSequenceManager.hpp.

Type of container for organizing SequenceData instances.

Definition at line 71 of file TypeSequenceManager.hpp.

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

Iterator for set_type.

Definition at line 67 of file TypeSequenceManager.hpp.

Type of container for organizing EntitySequence instances.

Definition at line 65 of file TypeSequenceManager.hpp.


Constructor & Destructor Documentation

Definition at line 10 of file TypeSequenceManager.cpp.

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

{
    // We assume that for there to be multiple sequences referencing
    // the same SequenceData, there must be some portion of the
    // SequenceData that is unused. Otherwise the sequences should
    // have been merged. Given that assumption, it is the case that
    // either a) a SequenceData is in availableList or b) the
    // SequenceData is referenced by exactly one sequence.

    // Delete every entity sequence
    for( iterator i = begin(); i != end(); ++i )
    {
        EntitySequence* seq = *i;
        // Check for case b) above
        if( seq->using_entire_data() )
        {
            // Delete sequence before data, because sequence
            // has a pointer to data and may try to dereference
            // that pointer during its destruction.
            SequenceData* data = seq->data();
            delete seq;
            delete data;
        }
        else
        {
            delete seq;
        }
    }
    sequenceSet.clear();

    // Case a) above
    for( data_iterator i = availableList.begin(); i != availableList.end(); ++i )
        delete *i;
    availableList.clear();
}

Member Function Documentation

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 840 of file TypeSequenceManager.cpp.

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

Referenced by get_memory_use().

{
    const unsigned long allocated_count = data->size();

    unsigned long bytes_per_ent, seq_size;
    const_iterator i = data->seqManData.firstSequence;
    ( *i )->get_const_memory_use( bytes_per_ent, seq_size );

    unsigned long other_ent_mem  = 0;
    unsigned long occupied_count = 0, entity_count = 0, sequence_count = 0;
    for( ; i != end() && ( *i )->data() == data; ++i )
    {
        occupied_count += ( *i )->size();
        ++sequence_count;

        EntityHandle start = std::max( first, ( *i )->start_handle() );
        EntityHandle stop  = std::min( last, ( *i )->end_handle() );
        if( stop < start ) continue;

        entity_count += stop - start + 1;
        other_ent_mem += ( *i )->get_per_entity_memory_use( start, stop );
    }

    unsigned long sum = sequence_count * seq_size + allocated_count * bytes_per_ent;

    // Watch for overflow
    assert( entity_count > 0 && occupied_count > 0 && allocated_count > 0 );
    if( std::numeric_limits< unsigned long >::max() / entity_count <= sum )
    {
        total_storage += sum * ( entity_count / occupied_count ) + other_ent_mem;
        entity_storage += sum * ( entity_count / allocated_count ) + other_ent_mem;
    }
    else
    {
        total_storage += sum * entity_count / occupied_count + other_ent_mem;
        entity_storage += sum * entity_count / allocated_count + other_ent_mem;
    }
}

Definition at line 153 of file TypeSequenceManager.hpp.

References sequenceSet.

    {
        return sequenceSet.begin();
    }

Definition at line 67 of file TypeSequenceManager.cpp.

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

Referenced by insert_sequence(), and notify_appended().

{
    iterator j = i;
    ++j;
    if( j == end() || ( *j )->data() != ( *i )->data() || ( *j )->start_handle() > ( *i )->end_handle() + 1 )
        return MB_SUCCESS;

    assert( ( *i )->end_handle() + 1 == ( *j )->start_handle() );
    return merge_internal( i, j );
}

Definition at line 78 of file TypeSequenceManager.cpp.

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

Referenced by insert_sequence(), and notify_prepended().

{
    if( i == begin() ) return MB_SUCCESS;

    iterator j = i;
    --j;
    if( ( *j )->data() != ( *i )->data() || ( *j )->end_handle() + 1 < ( *i )->start_handle() ) return MB_SUCCESS;

    assert( ( *j )->end_handle() + 1 == ( *i )->start_handle() );
    return merge_internal( i, j );
}
bool moab::TypeSequenceManager::check_valid_data ( const EntitySequence seq) const [private]

Definition at line 907 of file TypeSequenceManager.cpp.

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

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

{
    // Caller passed a sequence that should be contained, so cannot be empty
    if( empty() ) return false;

    // Make sure lastReferenced points to something
    if( !lastReferenced ) return false;

    const_iterator seqi = sequenceSet.lower_bound( lastReferenced );
    if( seqi == sequenceSet.end() || *seqi != lastReferenced ) return false;

    // Make sure passed sequence is in list
    const EntitySequence* seq2 = find( seq->start_handle() );
    if( seq2 != seq ) return false;

    // Check all sequences referencing the same SequenceData
    const SequenceData* data = seq->data();
    const_iterator i         = lower_bound( data->start_handle() );
    if( i != data->seqManData.firstSequence ) return false;

    if( i != begin() )
    {
        const_iterator j = i;
        --j;
        if( ( *j )->end_handle() >= data->start_handle() ) return false;
        if( ( *j )->data()->end_handle() >= data->start_handle() ) return false;
    }

    for( ;; )
    {
        seq2 = *i;
        ++i;
        if( i == end() ) return true;
        if( ( *i )->data() != data ) break;

        if( seq2->end_handle() >= ( *i )->start_handle() ) return false;
    }

    if( ( *i )->start_handle() <= data->end_handle() ) return false;
    if( ( *i )->data()->start_handle() <= data->end_handle() ) return false;

    return true;
}

Definition at line 595 of file TypeSequenceManager.cpp.

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

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

{
    const_iterator i = lower_bound( first );
    if( i == end() || ( *i )->start_handle() > first )
    {
#if 0
    // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call
    // MB_SET_ERR on it
    fprintf(
      stderr,
      "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)first
      );
#endif
        return MB_ENTITY_NOT_FOUND;
    }

    while( ( *i )->end_handle() < last )
    {
        EntityHandle prev_end = ( *i )->end_handle();
        ++i;
        if( i == end() || prev_end + 1 != ( *i )->start_handle() ) return MB_ENTITY_NOT_FOUND;
    }

    return MB_SUCCESS;
}

Definition at line 163 of file TypeSequenceManager.hpp.

References sequenceSet.

    {
        return sequenceSet.end();
    }

Remove a sequence.

Definition at line 259 of file TypeSequenceManager.cpp.

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(), erase(), and test_erase().

{
    EntitySequence* seq = *i;
    SequenceData* data  = seq->data();
    iterator j;

    // Check if we need to delete the referenced SequenceData also
    bool delete_data;
    if( seq->using_entire_data() )  // Only sequence
        delete_data = true;
    else if( data->seqManData.firstSequence != i )
    {  // Earlier sequence?
        delete_data = false;
        availableList.insert( data );
    }
    else
    {  // Later sequence ?
        j = i;
        ++j;
        delete_data = ( j == end() || ( *j )->data() != data );
        if( delete_data )
            availableList.erase( data );
        else
        {
            availableList.insert( data );
            data->seqManData.firstSequence = j;
        }
    }

    // Remove sequence, updating i to be next sequence
    j = i++;
    sequenceSet.erase( j );

    // Make sure lastReferenced isn't stale. It can only be NULL if
    // no sequences.
    if( lastReferenced == seq ) lastReferenced = sequenceSet.empty() ? 0 : *sequenceSet.begin();

    // Always delete sequence before the SequenceData it references.
    assert( 0 == find( seq->start_handle() ) );
    delete seq;
    if( delete_data )
        delete data;
    else
    {
        assert( check_valid_data( *data->seqManData.firstSequence ) );
        assert( lastReferenced != seq );
    }
    return i;
}
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 671 of file TypeSequenceManager.cpp.

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

{
    // First check that all entities in range are valid

    ErrorCode rval = check_valid_handles( NULL, first, last );
    if( MB_SUCCESS != rval ) return rval;

    // Now remove entities

    // Get first sequence intersecting range
    iterator i = lower_bound( first );
    if( i == end() )  // Shouldn't be possible given check_valid_handles call above.
        return MB_ENTITY_NOT_FOUND;

    // If range is entirely in interior of sequence, need to split sequence.
    if( ( *i )->start_handle() < first && ( *i )->end_handle() > last )
    {
        if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
        i = split_sequence( i, first );
        ( *i )->pop_front( last - first + 1 );
        assert( check_valid_data( *i ) );
        return MB_SUCCESS;
    }

    // If range doesn't entirely contain first sequence, remove some
    // handles from the end of the sequence and advance to the next
    // sequence.
    if( ( *i )->start_handle() < first )
    {
        if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
        ( *i )->pop_back( ( *i )->end_handle() - first + 1 );
        ++i;
    }

    // Destroy all sequences contained entirely within the range
    while( i != end() && ( *i )->end_handle() <= last )
        i = erase( i );

    // If necessary, remove entities from the beginning of the
    // last sequence.
    if( i != end() && ( *i )->start_handle() <= last )
    {
        if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
        ( *i )->pop_front( last - ( *i )->start_handle() + 1 );
        assert( check_valid_data( *i ) );
    }

    return MB_SUCCESS;
}
ErrorCode moab::TypeSequenceManager::erase ( Error error_handler,
EntityHandle  entity 
)

Definition at line 622 of file TypeSequenceManager.cpp.

References availableList, moab::EntitySequence::data(), moab::EntitySequence::end_handle(), 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().

{
    EntitySequence* seq = find( h );
    if( !seq )
    {
#if 0
    // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call
    // MB_SET_ERR on it
    fprintf(
      stderr,
      "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)h
      );
#endif
        return MB_ENTITY_NOT_FOUND;
    }

    if( seq->start_handle() == h )
    {
        if( seq->end_handle() != h )
        {
            if( seq->using_entire_data() ) availableList.insert( seq->data() );
            seq->pop_front( 1 );
            return MB_SUCCESS;
        }
        SequenceData* data = seq->data();
        bool delete_data;
        ErrorCode rval = remove_sequence( seq, delete_data );
        if( MB_SUCCESS != rval ) return rval;
        delete seq;
        if( delete_data ) delete data;
    }
    else if( seq->end_handle() == h )
    {
        if( seq->using_entire_data() ) availableList.insert( seq->data() );
        seq->pop_back( 1 );
    }
    else
    {
        iterator i = lower_bound( h );
        if( ( *i )->using_entire_data() ) availableList.insert( ( *i )->data() );
        i   = split_sequence( i, h );
        seq = *i;
        assert( seq->start_handle() == h );
        seq->pop_front( 1 );
    }

    return MB_SUCCESS;
}

Get EntitySequence for handle.

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

Definition at line 360 of file TypeSequenceManager.hpp.

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

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

{
    if( !lastReferenced )  // only null if empty
        return 0;
    else if( h >= lastReferenced->start_handle() && h <= lastReferenced->end_handle() )
        return lastReferenced;
    else
    {
        DummySequence seq( h );
        const_iterator i = sequenceSet.find( &seq );
        return i == end() ? 0 : ( lastReferenced = *i );
    }
}

Definition at line 373 of file TypeSequenceManager.hpp.

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

{
    if( !lastReferenced )  // only null if empty
        return 0;
    else if( h >= lastReferenced->start_handle() && h <= lastReferenced->end_handle() )
        return lastReferenced;
    else
    {
        DummySequence seq( h );
        iterator i = sequenceSet.find( &seq );
        return i == end() ? 0 : ( lastReferenced = *i );
    }
}

Definition at line 387 of file TypeSequenceManager.hpp.

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

{
    if( !lastReferenced )
    {  // only null if empty
        seq = 0;
        return MB_ENTITY_NOT_FOUND;
    }
    else if( h >= lastReferenced->start_handle() && h <= lastReferenced->end_handle() )
    {
        seq = lastReferenced;
        return MB_SUCCESS;
    }
    else
    {
        DummySequence ds( h );
        iterator i = sequenceSet.lower_bound( &ds );
        if( i == end() || ( *i )->start_handle() > h )
        {
            seq = 0;
            return MB_ENTITY_NOT_FOUND;
        }
        else
        {
            seq = lastReferenced = *i;
            return MB_SUCCESS;
        }
    }
}
ErrorCode moab::TypeSequenceManager::find ( EntityHandle  h,
const EntitySequence *&  seq 
) const [inline]

Definition at line 416 of file TypeSequenceManager.hpp.

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

{
    if( !lastReferenced )
    {  // only null if empty
        seq = 0;
        return MB_ENTITY_NOT_FOUND;
    }
    else if( h >= lastReferenced->start_handle() && h <= lastReferenced->end_handle() )
    {
        seq = lastReferenced;
        return MB_SUCCESS;
    }
    else
    {
        DummySequence ds( h );
        const_iterator i = sequenceSet.lower_bound( &ds );
        if( i == end() || ( *i )->start_handle() > h )
        {
            seq = 0;
            return MB_ENTITY_NOT_FOUND;
        }
        else
        {
            seq = lastReferenced = *i;
            return MB_SUCCESS;
        }
    }
}
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 420 of file TypeSequenceManager.cpp.

References end(), and lower_bound().

{
    const_iterator i = lower_bound( min_start_handle );
    if( i == end() ) return min_start_handle;

    if( ( *i )->start_handle() < min_start_handle + num_entities ) return min_start_handle;

    EntityHandle prev_end = ( *i )->end_handle();
    ++i;
    for( ; i != end(); prev_end = ( *i )->end_handle(), ++i )
    {
        EntityID len = ( *i )->start_handle() - prev_end - 1;
        if( len >= num_entities ) break;
    }

    if( prev_end + num_entities > max_end_handle )
        return 0;
    else
        return prev_end + 1;
}
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.

References availableList, and end().

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

{
    for( data_iterator i = availableList.begin(); i != availableList.end(); ++i )
    {
        if( ( *( *i )->seqManData.firstSequence )->values_per_entity() != values_per_ent ) continue;

        if( ( *i )->start_handle() > max_end_handle || ( *i )->end_handle() < min_start_handle ) continue;

        for( iterator j = ( *i )->seqManData.firstSequence;
             j != end() && ( *j )->start_handle() <= ( max_end_handle + 1 ) && ( *j )->data() == *i; ++j )
        {
            if( ( *j )->end_handle() + 1 < min_start_handle ) continue;
            if( ( *j )->start_handle() > ( *i )->start_handle() && ( *j )->start_handle() > min_start_handle )
            {
                append_out = false;
                return j;
            }
            if( ( *j )->end_handle() < ( *i )->end_handle() && ( *j )->end_handle() < max_end_handle )
            {
                append_out = true;
                return j;
            }
        }
    }

    return end();
}
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 463 of file TypeSequenceManager.cpp.

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(), regression_svn1952(), regression_svn1958(), regression_svn1960(), moab::SequenceManager::sequence_start_handle(), and test_find_free_sequence().

{
    if( max_end_handle < min_start_handle + num_entities - 1 ) return 0;

    EntityHandle result;
    iterator p, i = lower_bound( min_start_handle );
    range_data d = { num_entities, min_start_handle, max_end_handle, 0, 0 };

    if( i == end() )
    {
        data_out = 0;
        return min_start_handle;
    }
    else if( i == begin() )
    {
        if( ( *i )->values_per_entity() == num_verts )
        {
            d.first = ( *i )->data()->start_handle();
            d.last  = ( *i )->start_handle() - 1;
            if( check_range( d, true, result ) )
            {
                data_out = ( *i )->data();
                return result;
            }
        }
        d.first = min_start_handle;
        d.last  = ( *i )->data()->start_handle() - 1;
        if( check_range( d, true, result ) )
        {
            data_out = 0;
            // This will back up against the end of the seq data, so
            // size the data that way
            data_size = num_entities;
            return result;
        }
        p = i++;
    }
    else
    {
        p = i;
        --p;
    }

    for( ; i != end() && ( *i )->start_handle() < max_end_handle; p = i++ )
    {
        if( ( *p )->data() == ( *i )->data() )
        {
            if( ( *p )->values_per_entity() == num_verts )
            {
                d.first = ( *p )->end_handle() + 1;
                d.last  = ( *i )->start_handle() - 1;
                if( check_range( d, false, result ) )
                {
                    data_out = ( *p )->data();
                    return result;
                }
            }
        }
        else
        {
            if( ( *p )->values_per_entity() == num_verts )
            {
                d.first = ( *p )->end_handle() + 1;
                d.last  = ( *p )->data()->end_handle();
                if( check_range( d, false, result ) )
                {
                    data_out = ( *p )->data();
                    return result;
                }
            }
            if( ( *i )->values_per_entity() == num_verts )
            {
                d.first = ( *i )->data()->start_handle();
                d.last  = ( *i )->start_handle() - 1;
                if( check_range( d, true, result ) )
                {
                    data_out = ( *i )->data();
                    return result;
                }
            }
            d.first = ( *p )->data()->end_handle() + 1;
            d.last  = ( *i )->data()->start_handle() - 1;
            if( check_range( d, false, result ) )
            {
                data_out  = 0;
                data_size = d.last - d.first + 1;
                return result;
            }
        }
    }

    if( ( *p )->values_per_entity() == num_verts )
    {
        d.first = ( *p )->end_handle() + 1;
        d.last  = ( *p )->data()->end_handle();
        if( check_range( d, false, result ) )
        {
            data_out = ( *p )->data();
            return result;
        }
    }

    d.first = ( *p )->data()->end_handle() + 1;
    d.last  = max_end_handle;
    if( check_range( d, false, result ) )
    {
        data_out = 0;
        return result;
    }

    data_out = 0;
    return 0;
}
void moab::TypeSequenceManager::get_entities ( Range entities_out) const [inline]

Get handles for all entities in all sequences.

Definition at line 450 of file TypeSequenceManager.hpp.

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

Referenced by moab::SequenceManager::get_entities(), and test_get_entities().

{
    Range::iterator in = entities_out.begin();
    for( const_iterator i = begin(); i != end(); ++i )
        in = entities_out.insert( in, ( *i )->start_handle(), ( *i )->end_handle() );
}
void moab::TypeSequenceManager::get_entities ( std::vector< EntityHandle > &  entities_out) const [inline]

Get handles for all entities in all sequences.

Definition at line 457 of file TypeSequenceManager.hpp.

References begin(), and end().

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

Definition at line 445 of file TypeSequenceManager.hpp.

References lastReferenced.

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

{
    return lastReferenced; /* only NULL if TypeSequenceManager is empty */
}
void moab::TypeSequenceManager::get_memory_use ( unsigned long long &  total_entity_storage,
unsigned long long &  total_storage 
) const

Definition at line 829 of file TypeSequenceManager.cpp.

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().

{
    entity_storage = total_storage = 0;
    if( empty() ) return;

    EntityType mytype = TYPE_FROM_HANDLE( lastReferenced->start_handle() );
    int junk;
    get_memory_use( CREATE_HANDLE( mytype, MB_START_ID, junk ), CREATE_HANDLE( mytype, MB_END_ID, junk ),
                    entity_storage, total_storage );
}
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 881 of file TypeSequenceManager.cpp.

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

{
    entity_storage = total_storage = 0;

    while( first <= last )
    {
        const_iterator i = lower_bound( first );
        if( i == end() ) return;

        SequenceData* data = ( *i )->data();
        if( first < data->end_handle() ) { append_memory_use( first, last, data, entity_storage, total_storage ); }
        first = data->end_handle() + 1;
    }
}

Get number of entities represented by all sequences.

Definition at line 464 of file TypeSequenceManager.hpp.

References begin(), and end().

Referenced by moab::SequenceManager::get_number_entities(), make_basic_sequence(), and test_get_entities().

{
    EntityID count = 0;
    for( const_iterator i = begin(); i != end(); ++i )
        count += ( *i )->size();
    return count;
}

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 897 of file TypeSequenceManager.cpp.

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

{
    EntityID result = 0;
    for( const_iterator i = data->seqManData.firstSequence; i != end() && ( *i )->data() == data; ++i )
        result += ( *i )->size();

    return result;
}
unsigned long moab::TypeSequenceManager::get_sequence_count ( ) const [inline]

Definition at line 347 of file TypeSequenceManager.hpp.

References sequenceSet.

Referenced by get_number_sequences().

    {
        return sequenceSet.size();
    }

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.

References availableList, begin(), check_merge_next(), check_merge_prev(), check_valid_data(), moab::EntitySequence::data(), end(), moab::SequenceData::end_handle(), moab::EntitySequence::end_handle(), moab::TypeSequenceManager::SequenceDataPtr::firstSequence, lastReferenced, lower_bound(), MB_ALREADY_ALLOCATED, MB_FAILURE, MB_SUCCESS, moab::SequenceData::seqManData, sequenceSet, moab::SequenceData::start_handle(), moab::EntitySequence::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(), insert_seq(), replace_subsequence(), and test_insert_sequence_nomerge().

{
    if( !seq_ptr->data() ) return MB_FAILURE;

    if( seq_ptr->data()->start_handle() > seq_ptr->start_handle() ||
        seq_ptr->data()->end_handle() < seq_ptr->end_handle() || seq_ptr->end_handle() < seq_ptr->start_handle() )
        return MB_FAILURE;

    iterator i = lower_bound( seq_ptr->start_handle() );
    if( i != end() )
    {
        if( ( *i )->start_handle() <= seq_ptr->end_handle() ) return MB_ALREADY_ALLOCATED;
        if( seq_ptr->data() != ( *i )->data() && ( *i )->data()->start_handle() <= seq_ptr->data()->end_handle() )
            return MB_ALREADY_ALLOCATED;
    }

    if( i != begin() )
    {
        iterator j = i;
        --j;
        if( seq_ptr->data() != ( *j )->data() && ( *j )->data()->end_handle() >= seq_ptr->data()->start_handle() )
            return MB_ALREADY_ALLOCATED;
    }

    i = sequenceSet.insert( i, seq_ptr );

    // Merge with previous sequence ?
    if( seq_ptr->start_handle() > seq_ptr->data()->start_handle() && i != begin() )
    {
        if( MB_SUCCESS != check_merge_prev( i ) )
        {
            sequenceSet.erase( i );
            return MB_FAILURE;
        }
    }

    // Merge with next sequence ?
    if( ( *i )->end_handle() < ( *i )->data()->end_handle() )
    {
        if( MB_SUCCESS != check_merge_next( i ) )
        {
            sequenceSet.erase( i );
            return MB_FAILURE;
        }
    }

    // We merged adjacent sequences sharing a SequenceData, so
    // we can safely assume that unless this EntitySequence is
    // using the entire SequenceData, there are unused portions.
    if( !seq_ptr->using_entire_data() ) availableList.insert( seq_ptr->data() );

    // lastReferenced is only allowed to be NULL if there are
    // no sequences (avoids unnecessary if's in fast path).
    if( !lastReferenced ) lastReferenced = seq_ptr;

    // Each SequenceData has a pointer to the first EntitySequence
    // referencing it. Update that pointer if the new sequence is
    // the first one.
    if( ( *i )->start_handle() == ( *i )->data()->start_handle() || lower_bound( ( *i )->data()->start_handle() ) == i )
        ( *i )->data()->seqManData.firstSequence = i;

    assert( check_valid_data( seq_ptr ) );
    return MB_SUCCESS;
}
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 732 of file TypeSequenceManager.cpp.

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(), and test_is_free_handle().

{
    int junk;
    block_start = CREATE_HANDLE( TYPE_FROM_HANDLE( handle ), MB_START_ID, junk );
    block_end   = CREATE_HANDLE( TYPE_FROM_HANDLE( handle ), MB_END_ID, junk );

    iterator i = lower_bound( handle );
    if( i != end() )
    {
        block_end = ( *i )->start_handle() - 1;

        // If sequence contains handle, then already allocated
        if( ( *i )->start_handle() <= handle ) return MB_ALREADY_ALLOCATED;

        // Handle is not within an existing sequence, but is
        // within an existing SequenceData...
        if( ( *i )->data()->start_handle() <= handle )
        {
            // If values_per_entity don't match, can't put new entity
            // in existing SequenceData
            if( ( *i )->values_per_entity() != values_per_ent ) return MB_ALREADY_ALLOCATED;

            data_ptr_out = ( *i )->data();
            if( block_end == handle )
            {
                // Prepend to existing sequence
                seq_iter_out = i;
                block_start  = handle;
            }
            else
            {
                // Add new sequence to existing SequenceData
                seq_iter_out = end();
                if( i == begin() || ( *--i )->data() != data_ptr_out )
                    block_start = data_ptr_out->start_handle();
                else
                    block_start = ( *i )->end_handle() + 1;
            }
            return MB_SUCCESS;
        }
    }

    if( i != begin() )
    {
        --i;
        block_start = ( *i )->end_handle() + 1;

        // Handle is within previous sequence data...
        if( ( *i )->data()->end_handle() >= handle )
        {
            // If values_per_entity don't match, can't put new entity
            // in existing SequenceData
            if( ( *i )->values_per_entity() != values_per_ent ) return MB_ALREADY_ALLOCATED;

            data_ptr_out = ( *i )->data();
            if( block_start == handle )
            {
                // Append to existing sequence
                seq_iter_out = i;
                block_end    = handle;
            }
            else
            {
                // Add new sequence to existing SequenceData
                seq_iter_out = end();
                if( ++i == end() || ( *i )->data() != data_ptr_out )
                    block_end = data_ptr_out->end_handle();
                else
                    block_end = ( *i )->start_handle() - 1;
            }
            return MB_SUCCESS;
        }
    }

    seq_iter_out = end();
    data_ptr_out = 0;

    return MB_SUCCESS;
}
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 364 of file TypeSequenceManager.cpp.

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

Referenced by moab::SequenceManager::sequence_start_handle(), and test_is_free_sequence().

{
    data_out = 0;
    if( empty() ) return true;

    const_iterator i = lower_bound( start );
    if( i == end() )
    {
        --i;  // Safe because already tested empty()
        // If we don't overlap the last data object...
        if( ( *i )->data()->end_handle() < start ) return true;
        data_out = ( *i )->data();
        if( ( *i )->values_per_entity() != values_per_ent ) return false;
        // If we overlap a data object, we must be entirely inside of it
        return start + num_entities - 1 <= ( *i )->data()->end_handle();
    }

#ifndef NDEBUG
    if( i != begin() )
    {
        const_iterator j = i;
        --j;
        assert( ( *j )->end_handle() < start );
    }
#endif

    // Check if we fit in the block of free handles
    if( start + num_entities > ( *i )->start_handle() )  // start + num + 1 >= i->start
        return false;

    // Check if we overlap the data for the next sequence
    if( start + num_entities > ( *i )->data()->start_handle() )
    {
        data_out = ( *i )->data();
        if( ( *i )->values_per_entity() != values_per_ent ) return false;
        // If overlap, must be entirely contained
        return start >= data_out->start_handle() && start + num_entities - 1 <= data_out->end_handle();
    }

    // Check if we overlap the data for the previous sequence
    if( i != begin() )
    {
        --i;
        if( ( *i )->data()->end_handle() >= start )
        {
            data_out = ( *i )->data();
            if( ( *i )->values_per_entity() != values_per_ent ) return false;
            return start + num_entities - 1 <= ( *i )->data()->end_handle();
        }
    }

    // Unused handle block that overlaps no SequenceData
    return true;
}

Definition at line 579 of file TypeSequenceManager.cpp.

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

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

{
    int junk;
    const_iterator it = lower_bound( after_this );
    if( it == end() )
        return CREATE_HANDLE( TYPE_FROM_HANDLE( after_this ), MB_END_ID, junk );
    else if( ( *it )->start_handle() > after_this )
    {
        // Need to check against the sequence data first
        EntityHandle rhandle = ( *it )->data()->start_handle();
        return rhandle - 1;
    }
    else
        return 0;
}

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 174 of file TypeSequenceManager.hpp.

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(), replace_subsequence(), and test_lower_bound().

    {
        DummySequence f( h );
        return sequenceSet.lower_bound( &f );
    }

Definition at line 179 of file TypeSequenceManager.hpp.

References sequenceSet.

    {
        DummySequence f( h );
        return sequenceSet.lower_bound( &f );
    }

Definition at line 46 of file TypeSequenceManager.cpp.

References availableList, lastReferenced, MB_SUCCESS, and sequenceSet.

Referenced by check_merge_next(), and check_merge_prev().

{
    EntitySequence* dead = *j;
    sequenceSet.erase( j );
    ErrorCode rval = ( *i )->merge( *dead );
    if( MB_SUCCESS != rval )
    {
        sequenceSet.insert( dead );
        return rval;
    }

    if( lastReferenced == dead ) lastReferenced = *i;
    delete dead;

    // If merging results in no unused portions of the SequenceData,
    // remove it from the available list.
    if( ( *i )->using_entire_data() ) availableList.erase( ( *i )->data() );

    return MB_SUCCESS;
}

Notify that sequence was appended to.

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

Definition at line 813 of file TypeSequenceManager.cpp.

References availableList, and check_merge_next().

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

{
    ErrorCode rval = check_merge_next( seq );
    if( ( *seq )->using_entire_data() ) availableList.erase( ( *seq )->data() );

    return rval;
}

Notify that sequence was prepended to.

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

Definition at line 821 of file TypeSequenceManager.cpp.

References availableList, and check_merge_prev().

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

{
    ErrorCode rval = check_merge_prev( seq );
    if( ( *seq )->using_entire_data() ) availableList.erase( ( *seq )->data() );

    return rval;
}
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.

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

Referenced by erase(), and test_remove_sequence().

{
    // Remove sequence from set
    iterator i = lower_bound( seq_ptr->start_handle() );
    if( i == end() || *i != seq_ptr ) return MB_ENTITY_NOT_FOUND;
    sequenceSet.erase( i );

    // Check if this is the only sequence referencing its data
    if( seq_ptr->using_entire_data() )
        unreferenced_data = true;
    else
    {
        i                 = lower_bound( seq_ptr->data()->start_handle() );
        unreferenced_data = i == end() || ( *i )->data() != seq_ptr->data();
        if( unreferenced_data )
            availableList.erase( seq_ptr->data() );
        else
            seq_ptr->data()->seqManData.firstSequence = i;  // Might be 'i' already
    }

    if( lastReferenced == seq_ptr ) lastReferenced = sequenceSet.empty() ? 0 : *sequenceSet.begin();

    return MB_SUCCESS;
}
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.

References availableList, moab::EntitySequence::data(), end(), moab::EntitySequence::end_handle(), moab::TypeSequenceManager::SequenceDataPtr::firstSequence, insert_sequence(), lastReferenced, lower_bound(), MB_FAILURE, moab::SequenceData::move_tag_data(), n, 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(), and test_replace_subsequence().

{
    // Find the sequence of interest
    iterator i = lower_bound( seq_ptr->start_handle() );
    if( i == end() || ( *i )->data() == seq_ptr->data() ) return MB_FAILURE;
    // New sequence must be a subset of an existing one
    if( seq_ptr->start_handle() < ( *i )->start_handle() || seq_ptr->end_handle() > ( *i )->end_handle() )
        return MB_FAILURE;
    // New sequence's data must be new also, and cannot intersect
    // any existing sequence (just require that the data range
    // matches the sequence range for now)
    if( !seq_ptr->using_entire_data() ) return MB_FAILURE;
    // Copy tag data (move ownership of var-len data)
    SequenceData* const dead_data = ( *i )->data();
    dead_data->move_tag_data( seq_ptr->data(), tag_sizes, num_tag_sizes );

    // Split sequences sharing old data into two groups:
    // p->i : first sequence to i
    // i->n : i to one past last sequence
    iterator p, n = i;
    p = ( *i )->data()->seqManData.firstSequence;
    for( ++n; n != end() && ( *n )->data() == ( *i )->data(); ++n )
        ;

    // First subdivide EntitySequence as necessary
    // Move i to be the first sequence past the insertion point
    // such that the new order will be:
    // [p,i-1] seq_ptr [i,n]
    // where p == i if no previous sequence

    // Four possible cases:
    // 0. All entities in sequence are in new sequence
    // 1. Old entities in sequence before and after new sequence,
    //    requiring sequence to be split.
    // 2. Old entities after new sequence
    // 3. Old entities before new sequence
    const bool some_before = ( ( *i )->start_handle() < seq_ptr->start_handle() );
    const bool some_after  = ( ( *i )->end_handle() > seq_ptr->end_handle() );
    // Case 0
    if( !( some_before || some_after ) )
    {
        // Remove dead sequence from internal lists
        EntitySequence* seq = *i;
        iterator dead       = i;
        ++i;
        if( p == dead ) p = i;
        sequenceSet.erase( dead );

        // Delete old sequence
        delete seq;
        // Make sure lastReferenced isn't stale
        if( lastReferenced == seq ) lastReferenced = seq_ptr;
    }
    // Case 1
    else if( some_before && some_after )
    {
        i = split_sequence( i, seq_ptr->start_handle() );
        ( *i )->pop_front( seq_ptr->size() );
    }
    // Case 2
    else if( some_after )
    {
        ( *i )->pop_front( seq_ptr->size() );
    }
    // Case 3
    else
    {  // some_before
        ( *i )->pop_back( seq_ptr->size() );
        ++i;
    }

    // Now subdivide the underlying sequence data as necessary
    availableList.erase( dead_data );
    if( p != i )
    {
        iterator last = i;
        --last;
        SequenceData* new_data = ( *p )->create_data_subset( ( *p )->start_handle(), ( *last )->end_handle() );
        new_data->seqManData.firstSequence = p;

        for( ; p != i; ++p )
            ( *p )->data( new_data );
        // Copy tag data (move ownership of var-len data)
        dead_data->move_tag_data( new_data, tag_sizes, num_tag_sizes );
        if( !( *new_data->seqManData.firstSequence )->using_entire_data() ) availableList.insert( new_data );
    }
    if( i != n )
    {
        iterator last = n;
        --last;
        SequenceData* new_data = ( *i )->create_data_subset( ( *i )->start_handle(), ( *last )->end_handle() );
        new_data->seqManData.firstSequence = i;
        for( ; i != n; ++i )
            ( *i )->data( new_data );
        // Copy tag data (move ownership of var-len data)
        dead_data->move_tag_data( new_data, tag_sizes, num_tag_sizes );
        if( !( *new_data->seqManData.firstSequence )->using_entire_data() ) availableList.insert( new_data );
    }
    delete dead_data;

    // Put new sequence in lists
    return insert_sequence( seq_ptr );
}

split a sequence

Definition at line 721 of file TypeSequenceManager.cpp.

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

Referenced by erase(), and replace_subsequence().

{
    EntitySequence* seq = ( *i )->split( h );
    if( !seq ) return end();

    i = sequenceSet.insert( i, seq );
    assert( check_valid_data( *i ) );

    return i;
}

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 192 of file TypeSequenceManager.hpp.

References sequenceSet.

Referenced by moab::RangeSeqIntersectIter::find_invalid_range(), and test_upper_bound().

    {
        DummySequence f( h );
        return sequenceSet.upper_bound( &f );
    }

Member Data Documentation

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines