Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
SequenceData.cpp
Go to the documentation of this file.
1 #include "SequenceData.hpp"
2 #include "SysUtil.hpp"
3 #include "VarLenTag.hpp"
4 #include <cassert>
5 
6 namespace moab
7 {
8 
10 {
11  for( int i = -numSequenceData; i <= (int)numTagData; ++i )
12  free( arraySet[i] );
13  free( arraySet - numSequenceData );
14 }
15 
16 void* SequenceData::create_data( int index, int bytes_per_ent, const void* initial_value )
17 {
18  char* array = (char*)malloc( bytes_per_ent * size() );
19  if( initial_value ) SysUtil::setmem( array, initial_value, bytes_per_ent, size() );
20 
21  arraySet[index] = array;
22  return array;
23 }
24 
25 void* SequenceData::create_sequence_data( int array_num, int bytes_per_ent, const void* initial_value )
26 {
27  const int index = -1 - array_num;
28  assert( array_num < numSequenceData );
29  assert( !arraySet[index] );
30  return create_data( index, bytes_per_ent, initial_value );
31 }
32 
33 void* SequenceData::create_custom_data( int array_num, size_t total_bytes )
34 {
35  const int index = -1 - array_num;
36  assert( array_num < numSequenceData );
37  assert( !arraySet[index] );
38 
39  void* array = malloc( total_bytes );
40  arraySet[index] = array;
41  return array;
42 }
43 
45 {
46  assert( !arraySet[0] );
47  const size_t s = sizeof( AdjacencyDataType* ) * size();
48  arraySet[0] = malloc( s );
49  memset( arraySet[0], 0, s );
50  return reinterpret_cast< AdjacencyDataType* >( arraySet[0] );
51 }
52 
53 void SequenceData::increase_tag_count( unsigned amount )
54 {
55  void** list = arraySet - numSequenceData;
56  const size_t sz = sizeof( void* ) * ( numSequenceData + numTagData + amount + 1 );
57  void** new_list = (void**)realloc( list, sz );
58  if( !new_list )
59  {
60  fprintf( stderr, "SequenceData::increase_tag_count(): reallocation of list failed\n" );
61  // Note: free(list) will be called in the destructor
62  return;
63  }
64  else
65  list = new_list;
66  arraySet = list + numSequenceData;
67  memset( arraySet + numTagData + 1, 0, sizeof( void* ) * amount );
68  numTagData += amount;
69 }
70 
71 void* SequenceData::allocate_tag_array( int tag_num, int bytes_per_ent, const void* default_value )
72 {
73  if( (unsigned)tag_num >= numTagData ) increase_tag_count( tag_num - numTagData + 1 );
74 
75  assert( !arraySet[tag_num + 1] );
76  return create_data( tag_num + 1, bytes_per_ent, default_value );
77 }
78 
79 SequenceData* SequenceData::subset( EntityHandle start, EntityHandle end, const int* sequence_data_sizes ) const
80 {
81  return new SequenceData( this, start, end, sequence_data_sizes );
82 }
83 
85  EntityHandle start,
86  EntityHandle end,
87  const int* sequence_data_sizes )
88  : numSequenceData( from->numSequenceData ), numTagData( from->numTagData ), startHandle( start ), endHandle( end )
89 {
90  assert( start <= end );
91  assert( from != 0 );
92  assert( from->start_handle() <= start );
93  assert( from->end_handle() >= end );
94 
95  void** array = (void**)malloc( sizeof( void* ) * ( numSequenceData + numTagData + 1 ) );
96  arraySet = array + numSequenceData;
97  const size_t offset = start - from->start_handle();
98  const size_t count = end - start + 1;
99 
100  for( int i = 0; i < numSequenceData; ++i )
101  copy_data_subset( -1 - i, sequence_data_sizes[i], from->get_sequence_data( i ), offset, count );
102  copy_data_subset( 0, sizeof( AdjacencyDataType* ), from->get_adjacency_data(), offset, count );
103  for( unsigned i = 1; i <= numTagData; ++i )
104  arraySet[i] = 0;
105 }
106 
107 void SequenceData::copy_data_subset( int index, int size_per_ent, const void* source, size_t offset, size_t count )
108 {
109  if( !source )
110  arraySet[index] = 0;
111  else
112  {
113  arraySet[index] = malloc( count * size_per_ent );
114  memcpy( arraySet[index], (const char*)source + offset * size_per_ent, count * size_per_ent );
115  }
116 }
117 
118 void SequenceData::move_tag_data( SequenceData* destination, const int* tag_sizes, int num_tag_sizes )
119 {
120  assert( destination->start_handle() >= start_handle() );
121  assert( destination->end_handle() <= end_handle() );
122  const size_t offset = destination->start_handle() - start_handle();
123  const size_t count = destination->size();
124  if( destination->numTagData < numTagData ) destination->increase_tag_count( numTagData - destination->numTagData );
125 
126  for( unsigned i = 1; i <= numTagData; ++i )
127  {
128  if( !arraySet[i] ) continue;
129 
130  assert( i <= (unsigned)num_tag_sizes );
131  if( num_tag_sizes )
132  {
133  } // empty line to prevent compiler warning
134 
135  const int tag_size = tag_sizes[i - 1];
136  if( !destination->arraySet[i] ) destination->arraySet[i] = malloc( count * tag_size );
137  memcpy( destination->arraySet[i], reinterpret_cast< char* >( arraySet[i] ) + offset * tag_size,
138  count * tag_size );
139  }
140 }
141 
142 void SequenceData::release_tag_data( const int* tag_sizes, int num_tag_sizes )
143 {
144  assert( num_tag_sizes >= (int)numTagData );
145  if( num_tag_sizes )
146  {
147  } // empty line to prevent compiler warning
148  for( unsigned i = 0; i < numTagData; ++i )
149  release_tag_data( i, tag_sizes[i] );
150 }
151 
152 void SequenceData::release_tag_data( int tag_num, int tag_size )
153 {
154  if( (unsigned)tag_num < numTagData )
155  {
156  if( tag_size == MB_VARIABLE_LENGTH && arraySet[tag_num + 1] )
157  {
158  VarLenTag* iter = reinterpret_cast< VarLenTag* >( arraySet[tag_num + 1] );
159  VarLenTag* const end = iter + size();
160  for( ; iter != end; ++iter )
161  iter->clear();
162  }
163  free( arraySet[tag_num + 1] );
164  arraySet[tag_num + 1] = 0;
165  }
166 }
167 
168 } // namespace moab