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