moab
|
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