Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
SequenceData.cpp
Go to the documentation of this file.
00001 #include "SequenceData.hpp"
00002 #include "SysUtil.hpp"
00003 #include "VarLenTag.hpp"
00004 #include <cassert>
00005 
00006 namespace moab
00007 {
00008 
00009 SequenceData::~SequenceData()
00010 {
00011     for( int i = -numSequenceData; i <= (int)numTagData; ++i )
00012         free( arraySet[i] );
00013     free( arraySet - numSequenceData );
00014 }
00015 
00016 void* SequenceData::create_data( int index, int bytes_per_ent, const void* initial_value )
00017 {
00018     char* array = (char*)malloc( bytes_per_ent * size() );
00019     if( initial_value ) SysUtil::setmem( array, initial_value, bytes_per_ent, size() );
00020 
00021     arraySet[index] = array;
00022     return array;
00023 }
00024 
00025 void* SequenceData::create_sequence_data( int array_num, int bytes_per_ent, const void* initial_value )
00026 {
00027     const int index = -1 - array_num;
00028     assert( array_num < numSequenceData );
00029     assert( !arraySet[index] );
00030     return create_data( index, bytes_per_ent, initial_value );
00031 }
00032 
00033 void* SequenceData::create_custom_data( int array_num, size_t total_bytes )
00034 {
00035     const int index = -1 - array_num;
00036     assert( array_num < numSequenceData );
00037     assert( !arraySet[index] );
00038 
00039     void* array     = malloc( total_bytes );
00040     arraySet[index] = array;
00041     return array;
00042 }
00043 
00044 SequenceData::AdjacencyDataType* SequenceData::allocate_adjacency_data()
00045 {
00046     assert( !arraySet[0] );
00047     const size_t s = sizeof( AdjacencyDataType* ) * size();
00048     arraySet[0]    = malloc( s );
00049     memset( arraySet[0], 0, s );
00050     return reinterpret_cast< AdjacencyDataType* >( arraySet[0] );
00051 }
00052 
00053 void SequenceData::increase_tag_count( unsigned amount )
00054 {
00055     void** list     = arraySet - numSequenceData;
00056     const size_t sz = sizeof( void* ) * ( numSequenceData + numTagData + amount + 1 );
00057     void** new_list = (void**)realloc( list, sz );
00058     if( !new_list )
00059     {
00060         fprintf( stderr, "SequenceData::increase_tag_count(): reallocation of list failed\n" );
00061         // Note: free(list) will be called in the destructor
00062         return;
00063     }
00064     else
00065         list = new_list;
00066     arraySet = list + numSequenceData;
00067     memset( arraySet + numTagData + 1, 0, sizeof( void* ) * amount );
00068     numTagData += amount;
00069 }
00070 
00071 void* SequenceData::allocate_tag_array( int tag_num, int bytes_per_ent, const void* default_value )
00072 {
00073     if( (unsigned)tag_num >= numTagData ) increase_tag_count( tag_num - numTagData + 1 );
00074 
00075     assert( !arraySet[tag_num + 1] );
00076     return create_data( tag_num + 1, bytes_per_ent, default_value );
00077 }
00078 
00079 SequenceData* SequenceData::subset( EntityHandle start, EntityHandle end, const int* sequence_data_sizes ) const
00080 {
00081     return new SequenceData( this, start, end, sequence_data_sizes );
00082 }
00083 
00084 SequenceData::SequenceData( const SequenceData* from,
00085                             EntityHandle start,
00086                             EntityHandle end,
00087                             const int* sequence_data_sizes )
00088     : numSequenceData( from->numSequenceData ), numTagData( from->numTagData ), startHandle( start ), endHandle( end )
00089 {
00090     assert( start <= end );
00091     assert( from != 0 );
00092     assert( from->start_handle() <= start );
00093     assert( from->end_handle() >= end );
00094 
00095     void** array        = (void**)malloc( sizeof( void* ) * ( numSequenceData + numTagData + 1 ) );
00096     arraySet            = array + numSequenceData;
00097     const size_t offset = start - from->start_handle();
00098     const size_t count  = end - start + 1;
00099 
00100     for( int i = 0; i < numSequenceData; ++i )
00101         copy_data_subset( -1 - i, sequence_data_sizes[i], from->get_sequence_data( i ), offset, count );
00102     copy_data_subset( 0, sizeof( AdjacencyDataType* ), from->get_adjacency_data(), offset, count );
00103     for( unsigned i = 1; i <= numTagData; ++i )
00104         arraySet[i] = 0;
00105 }
00106 
00107 void SequenceData::copy_data_subset( int index, int size_per_ent, const void* source, size_t offset, size_t count )
00108 {
00109     if( !source )
00110         arraySet[index] = 0;
00111     else
00112     {
00113         arraySet[index] = malloc( count * size_per_ent );
00114         memcpy( arraySet[index], (const char*)source + offset * size_per_ent, count * size_per_ent );
00115     }
00116 }
00117 
00118 void SequenceData::move_tag_data( SequenceData* destination, const int* tag_sizes, int num_tag_sizes )
00119 {
00120     assert( destination->start_handle() >= start_handle() );
00121     assert( destination->end_handle() <= end_handle() );
00122     const size_t offset = destination->start_handle() - start_handle();
00123     const size_t count  = destination->size();
00124     if( destination->numTagData < numTagData ) destination->increase_tag_count( numTagData - destination->numTagData );
00125 
00126     for( unsigned i = 1; i <= numTagData; ++i )
00127     {
00128         if( !arraySet[i] ) continue;
00129 
00130         assert( i <= (unsigned)num_tag_sizes );
00131         if( num_tag_sizes )
00132         {
00133         }  // empty line to prevent compiler warning
00134 
00135         const int tag_size = tag_sizes[i - 1];
00136         if( !destination->arraySet[i] ) destination->arraySet[i] = malloc( count * tag_size );
00137         memcpy( destination->arraySet[i], reinterpret_cast< char* >( arraySet[i] ) + offset * tag_size,
00138                 count * tag_size );
00139     }
00140 }
00141 
00142 void SequenceData::release_tag_data( const int* tag_sizes, int num_tag_sizes )
00143 {
00144     assert( num_tag_sizes >= (int)numTagData );
00145     if( num_tag_sizes )
00146     {
00147     }  // empty line to prevent compiler warning
00148     for( unsigned i = 0; i < numTagData; ++i )
00149         release_tag_data( i, tag_sizes[i] );
00150 }
00151 
00152 void SequenceData::release_tag_data( int tag_num, int tag_size )
00153 {
00154     if( (unsigned)tag_num < numTagData )
00155     {
00156         if( tag_size == MB_VARIABLE_LENGTH && arraySet[tag_num + 1] )
00157         {
00158             VarLenTag* iter      = reinterpret_cast< VarLenTag* >( arraySet[tag_num + 1] );
00159             VarLenTag* const end = iter + size();
00160             for( ; iter != end; ++iter )
00161                 iter->clear();
00162         }
00163         free( arraySet[tag_num + 1] );
00164         arraySet[tag_num + 1] = 0;
00165     }
00166 }
00167 
00168 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines