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