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