tag.cpp 19.7 KB
Newer Older
Kirill Terekhov's avatar
Kirill Terekhov committed
1
2
3
4
5
#include "inmost.h"
#if defined(USE_MESH)

namespace INMOST
{
Kirill Terekhov's avatar
Kirill Terekhov committed
6
7
8
9
10
11
12
13
	const char * DataTypeName(DataType t)
	{
		switch(t)
		{
			case DATA_REAL:      return "REAL";
			case DATA_INTEGER:   return "INTEGER";
			case DATA_BULK:      return "BULK";
			case DATA_REFERENCE: return "REFERENCE";
Kirill Terekhov's avatar
Kirill Terekhov committed
14
			case DATA_REMOTE_REFERENCE: return "REMOTE_REFERENCE";
15
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
16
			case DATA_VARIABLE:  return "VARIABLE";
17
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
18
19
20
21
22
23
24
25
26
27
28
29
		}
		return "UNKNOWN";
	}


	__INLINE static INMOST_DATA_ENUM_TYPE DataTypeBytesSize(DataType t)
	{
		switch(t)
		{
			case DATA_BULK:      return sizeof(INMOST_DATA_BULK_TYPE);
			case DATA_INTEGER:   return sizeof(INMOST_DATA_INTEGER_TYPE);
			case DATA_REAL:      return sizeof(INMOST_DATA_REAL_TYPE);
Kirill Terekhov's avatar
Kirill Terekhov committed
30
			case DATA_REMOTE_REFERENCE:      return sizeof(RemoteHandleType);
Kirill Terekhov's avatar
Kirill Terekhov committed
31
			case DATA_REFERENCE: return sizeof(HandleType);
32
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
33
			case DATA_VARIABLE:  return sizeof(variable);
34
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
35
36
37
		}
		return 0;
	}
38
39
40
41
42
43
44
45
46
	
	__INLINE static INMOST_DATA_ENUM_TYPE DataTypePackedBytesSize(DataType t)
	{
		switch(t)
		{
			case DATA_BULK:      return sizeof(INMOST_DATA_BULK_TYPE);
			case DATA_INTEGER:   return sizeof(INMOST_DATA_INTEGER_TYPE);
			case DATA_REAL:      return sizeof(INMOST_DATA_REAL_TYPE);
			case DATA_REMOTE_REFERENCE: throw -1; //todo, exchange of this data type is not yet supported
47
			case DATA_REFERENCE: return sizeof(HandleType); //todo, exchange of this data type is not yet supported
48
49
50
51
52
53
#if defined(USE_AUTODIFF)
			case DATA_VARIABLE:  return sizeof(Sparse::Row::entry);
#endif
		}
		return 0;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
54
55
56
57
58
59
60
61
62
63


	__INLINE static INMOST_DATA_ENUM_TYPE VariableDataSize(DataType t)
	{
		switch(t)
		{
			case DATA_REAL:      return sizeof(inner_real_array);
			case DATA_INTEGER:   return sizeof(inner_integer_array);
			case DATA_BULK:      return sizeof(inner_bulk_array);
			case DATA_REFERENCE: return sizeof(inner_reference_array);
Kirill Terekhov's avatar
Kirill Terekhov committed
64
			case DATA_REMOTE_REFERENCE: return sizeof(inner_remote_reference_array);
65
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
66
			case DATA_VARIABLE:  return sizeof(inner_variable_array);
67
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
68
69
70
		}
		return 0;
	}
71
72
73
74
75
	
	INMOST_DATA_ENUM_TYPE Tag::GetPackedBytesSize() const
	{
		return DataTypePackedBytesSize(GetDataType());
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
76

Kirill Terekhov's avatar
Kirill Terekhov committed
77
78
79
80
	Tag::~Tag() 
	{
		mem = NULL;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
81

Kirill Terekhov's avatar
Kirill Terekhov committed
82
83
84
85
	Tag::Tag() 
	{
		mem = NULL;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
86

Kirill Terekhov's avatar
Kirill Terekhov committed
87
88
89
90
	Tag::Tag(const Tag & other) 
	{
		mem = other.mem;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
91

Kirill Terekhov's avatar
Kirill Terekhov committed
92
93
94
95
96
	void TagManager::CopyData(const Tag & t, void * adata, const void * bdata)
	{
		
		INMOST_DATA_ENUM_TYPE data_size = t.GetSize();
		INMOST_DATA_ENUM_TYPE bytes = t.GetBytesSize();
Kirill Terekhov's avatar
Kirill Terekhov committed
97
		DataType type = t.GetDataType();
Kirill Terekhov's avatar
Kirill Terekhov committed
98
99
100
101
102
103
104
		if( data_size == ENUMUNDEF ) //variable size array
		{
			if( adata != NULL ) TagManager::DestroyVariableData(t,adata);
			if( type == DATA_REAL )           new (adata) inner_real_array     (*static_cast<const inner_real_array      * >(bdata));
			else if( type == DATA_INTEGER )   new (adata) inner_integer_array  (*static_cast<const inner_integer_array   * >(bdata));
			else if( type == DATA_BULK )      new (adata) inner_bulk_array     (*static_cast<const inner_bulk_array      * >(bdata));
			else if( type == DATA_REFERENCE ) new (adata) inner_reference_array(*static_cast<const inner_reference_array * >(bdata));
Kirill Terekhov's avatar
Kirill Terekhov committed
105
106
			else if( type == DATA_REMOTE_REFERENCE ) 
											  new (adata) inner_remote_reference_array(*static_cast<const inner_remote_reference_array * >(bdata));
107
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
108
			else if( type == DATA_VARIABLE )  new (adata) inner_variable_array (*static_cast<const inner_variable_array  * >(bdata));
109
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
110
		}
111
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
112
113
114
115
116
		else if( type == DATA_VARIABLE ) //have to call constructor
		{
			for(INMOST_DATA_ENUM_TYPE k = 0; k < data_size; ++k)
				new (static_cast<variable *>(adata)+k) variable(*(static_cast<const variable *>(bdata)+k));
		}
117
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
		else // fixed size array
			memcpy(adata,bdata,data_size*bytes);
	}
	void TagManager::DestroyVariableData(const Tag & t, void * adata)
	{
		INMOST_DATA_ENUM_TYPE data_size = t.GetSize();
		if( data_size == ENUMUNDEF && adata != NULL ) //variable size array
		{
			DataType type = t.GetDataType();
			if( type == DATA_REAL ) 
			{
				(*static_cast<inner_real_array *> (adata)).~inner_real_array();
				new (adata) inner_real_array(); //reinitialize for reuse
			}
			else if( type == DATA_INTEGER ) 
			{
				(*static_cast<inner_integer_array *> (adata)).~inner_integer_array();
				new (adata) inner_integer_array();
			}
			else if( type == DATA_BULK ) 
			{
				(*static_cast<inner_bulk_array *> (adata)).~inner_bulk_array();
				new (adata) inner_bulk_array();
			}
			else if( type == DATA_REFERENCE ) 
			{
				(*static_cast<inner_reference_array *> (adata)).~inner_reference_array();
				new (adata) inner_reference_array();
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
147
			else if( type == DATA_REMOTE_REFERENCE ) 
148
149
150
151
			{
				(*static_cast<inner_remote_reference_array *> (adata)).~inner_remote_reference_array();
				new (adata) inner_remote_reference_array();
			}
152
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
153
154
155
156
157
			else if( type == DATA_VARIABLE ) 
			{
				(*static_cast<inner_variable_array *> (adata)).~inner_variable_array();
				new (adata) inner_variable_array();
			}
158
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
159
160
		}
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
161
162
163
	
	TagMemory::TagMemory(Mesh * m, const TagMemory & other)
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
164
		for(int i = 0; i < NUM_ELEMENT_TYPS; i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
165
		{
166
167
			pos[i]	   = other.pos[i];
			sparse[i]  = other.sparse[i];
Kirill Terekhov's avatar
Kirill Terekhov committed
168
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
169
170
		tagname		   = other.tagname;
		dtype		   = other.dtype;
Kirill Terekhov's avatar
Kirill Terekhov committed
171
		bulk_data_type = other.bulk_data_type;
Kirill Terekhov's avatar
Kirill Terekhov committed
172
173
174
175
		m_link         = m;
		size           = other.size;
		record_size    = other.record_size;
		bytes_size     = other.bytes_size;
176
		print_tag      = other.print_tag; //Temporary solution: @see Mesh::file_options
Kirill Terekhov's avatar
Kirill Terekhov committed
177
178
179
180
	}
	
	TagMemory & TagMemory::operator =(TagMemory const & other)
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
181
		for(int i = 0; i < NUM_ELEMENT_TYPS; i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
182
		{
183
184
			pos[i]     = other.pos[i];
			sparse[i]  = other.sparse[i];
Kirill Terekhov's avatar
Kirill Terekhov committed
185
		}
186
187
188
189
190
191
192
193
194
		tagname        = other.tagname;
		dtype          = other.dtype;
		bulk_data_type = other.bulk_data_type;
		m_link         = other.m_link;
		size           = other.size;
		record_size    = other.record_size;
		bytes_size     = other.bytes_size;
		print_tag      = other.print_tag; //Temporary solution: @see Mesh::file_options
		return *this;
Kirill Terekhov's avatar
Kirill Terekhov committed
195
196
197
198
	}
	
	TagMemory::TagMemory()
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
199
		for(int i = 0; i < NUM_ELEMENT_TYPS; i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
200
201
202
203
204
		{
			pos[i]	= ENUMUNDEF;
			sparse[i] = false;
		}
		tagname = "";
205
		print_tag = true;
Kirill Terekhov's avatar
Kirill Terekhov committed
206
207
208
209
210
	}
	
	Tag::Tag(Mesh * m, std::string name, DataType _dtype,INMOST_DATA_ENUM_TYPE size)
	{
		mem = new TagMemory();
Kirill Terekhov's avatar
Kirill Terekhov committed
211
		for(int i = 0; i < NUM_ELEMENT_TYPS; i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
212
213
214
215
216
217
218
219
220
221
222
223
		{
			mem->pos[i]	= ENUMUNDEF;
			mem->sparse[i] = false;
		}
		mem->tagname	= name;
		mem->dtype		= _dtype;
		mem->size		= size;
		switch(mem->dtype)
		{
			case DATA_BULK:      mem->bulk_data_type = INMOST_MPI_DATA_BULK_TYPE;    break;
			case DATA_REAL:      mem->bulk_data_type = INMOST_MPI_DATA_REAL_TYPE;    break;
			case DATA_INTEGER:   mem->bulk_data_type = INMOST_MPI_DATA_INTEGER_TYPE; break;
Kirill Terekhov's avatar
Kirill Terekhov committed
224
			case DATA_REFERENCE: mem->bulk_data_type = INMOST_MPI_DATA_ENUM_TYPE;    break;
Kirill Terekhov's avatar
Kirill Terekhov committed
225
			case DATA_REMOTE_REFERENCE: mem->bulk_data_type = INMOST_MPI_DATATYPE_NULL;    break; //should never send this
226
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
227
228
229
230
			case DATA_VARIABLE:
				if( !Sparse::HaveRowEntryType() ) Sparse::CreateRowEntryType();
				mem->bulk_data_type = Sparse::GetRowEntryType();
				break; 
231
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
232
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
233
		mem->bytes_size = DataTypeBytesSize(mem->dtype);
Kirill Terekhov's avatar
Kirill Terekhov committed
234
235
236
		if(mem->size == ENUMUNDEF )
			mem->record_size = VariableDataSize(mem->dtype);
		else
Kirill Terekhov's avatar
Kirill Terekhov committed
237
			mem->record_size = mem->size * mem->bytes_size;
Kirill Terekhov's avatar
Kirill Terekhov committed
238
239
		mem->m_link = m;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
240
	TagManager::TagManager()
Kirill Terekhov's avatar
Kirill Terekhov committed
241
242
	{
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
243
	TagManager::TagManager(const TagManager & other)
Kirill Terekhov's avatar
Kirill Terekhov committed
244
245
	{
		tags.resize(other.tags.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
246
		dense_data.resize(other.dense_data.size(),dense_sub_type(0));
Kirill Terekhov's avatar
Kirill Terekhov committed
247
		for(tag_array_type::size_type i = 0; i < other.tags.size(); i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
248
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
249
			tags[i].mem = new TagMemory(dynamic_cast<Mesh *>(this),*other.tags[i].mem);
Kirill Terekhov's avatar
Kirill Terekhov committed
250
251
			for(ElementType etype = NODE; etype <= MESH; etype = etype << 1)
				if( tags[i].isDefined(etype) && !tags[i].isSparse(etype) )
Kirill Terekhov's avatar
Kirill Terekhov committed
252
253
254
255
				{
					dense_data[tags[i].GetPosition(etype)] = dense_sub_type(tags[i].GetRecordSize());
					//tags[i].AllocateData(etype);
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
256
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
257
		
Kirill Terekhov's avatar
Kirill Terekhov committed
258
259
260
261
		//The rest of the data should be allocated and copied while copying data of
		//individual elements
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
262
	TagManager & TagManager::operator =(TagManager const & other)
Kirill Terekhov's avatar
Kirill Terekhov committed
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
	{

		//for(tag_iterator it = tags.begin(); it != tags.end(); it++)
		//{
		//	for(ElementType etype = NODE; etype <= MESH; etype = etype << 1 )
		//		if( it->isDefined(etype) && !it->isSparse(etype) && it->GetSize() == ENUMUNDEF )
		//		{
		//			INMOST_DATA_ENUM_TYPE record_size = it->GetRecordSize();
		//			TagManager::dense_sub_type & arr = dense_data[it->GetPosition(etype)];
		//			TagManager::dense_sub_type::iterator jt = arr.begin();
		//			switch(it->GetDataType())
		//			{
		//				case DATA_REAL:      while( jt != arr.end() ) { void * p = static_cast<void *>(&*jt); if( p != NULL ) (*static_cast<inner_real_array      *>( p )).~inner_real_array();      jt+=record_size; }  break;
		//				case DATA_INTEGER:   while( jt != arr.end() ) { void * p = static_cast<void *>(&*jt); if( p != NULL ) (*static_cast<inner_integer_array   *>( p )).~inner_integer_array();   jt+=record_size; }  break;
		//				case DATA_BULK:      while( jt != arr.end() ) { void * p = static_cast<void *>(&*jt); if( p != NULL ) (*static_cast<inner_bulk_array      *>( p )).~inner_bulk_array();      jt+=record_size; }  break;
		//				case DATA_REFERENCE: while( jt != arr.end() ) { void * p = static_cast<void *>(&*jt); if( p != NULL ) (*static_cast<inner_reference_array *>( p )).~inner_reference_array(); jt+=record_size; }  break;
		//			}
		//		}
		//	delete it->mem;
		//}
		tags.resize(other.tags.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
284
		dense_data.clear();
Kirill Terekhov's avatar
Kirill Terekhov committed
285
286
		dense_data.resize(other.dense_data.size(),dense_sub_type(0));
		for(tag_array_type::size_type i = 0; i < other.tags.size(); i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
287
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
288
			tags[i].mem = new TagMemory(dynamic_cast<Mesh *>(this),*other.tags[i].mem);
Kirill Terekhov's avatar
Kirill Terekhov committed
289
290
			for(ElementType etype = NODE; etype <= MESH; etype = etype << 1)
				if( tags[i].isDefined(etype) && !tags[i].isSparse(etype) )
Kirill Terekhov's avatar
Kirill Terekhov committed
291
292
293
294
				{
					dense_data[tags[i].GetPosition(etype)] = dense_sub_type(tags[i].GetRecordSize());
					//tags[i].AllocateData(etype);
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
295
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
296
297
		for(int i = 0; i < 6; i++)
			sparse_data[i].clear();
Kirill Terekhov's avatar
Kirill Terekhov committed
298
299
300
301
302
303
304
305
		//~ sparse_data.resize(other.sparse_data.size());
		//The rest of the data should be allocated and copied while copying data of
		//individual elements
		return *this;
	}
	
	TagManager::~TagManager()
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
306
307
		dense_data.clear();
		for(int i = 0; i < 6; i++) sparse_data[i].clear();
Kirill Terekhov's avatar
Kirill Terekhov committed
308
309
310
311
312
313
314
315
316
		for(tag_iterator it = tags.begin(); it != tags.end(); it++) delete it->mem;
		tags.clear();
	}
	
	
	
	Tag TagManager::CreateTag(Mesh *m, std::string name, DataType dtype, ElementType etype,ElementType sparse, INMOST_DATA_ENUM_TYPE size)
	{
		Tag new_tag;
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
317
318
319
#if !defined(LAZY_SPARSE_ALLOCATION)
		bool need_sparse[6] = {false,false,false,false,false,false};
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
320
		for(tag_array_type::size_type i = 0; i < tags.size(); i++)
321
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
322
323
			if( tags[i].GetTagName() == name )
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
324
325
326
327
328
				assert( tags[i].GetDataType() == dtype && (size == ENUMUNDEF || size == tags[i].GetSize()) );
				//if( tags[i].GetDataType() != dtype || (size != ENUMUNDEF && size != tags[i].GetSize()) )
				//{
				//	throw TagExists;
				//}
Kirill Terekhov's avatar
Kirill Terekhov committed
329
330
331
				new_tag = tags[i];
				break;
			}
332
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
333
334
335
		if( !new_tag.isValid() )
		{
			new_tag = Tag(m,name,dtype,size);
Kirill Terekhov's avatar
Kirill Terekhov committed
336
337
338
#if defined(USE_OMP)
#pragma omp critical
#endif
339
340
341
			{
				tags.push_back(new_tag);
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
342
343
344
345
346
347
348
349
350
		}
		for(ElementType mask = NODE; mask <= MESH; mask = mask << 1)
		{
			if( (mask & etype) && new_tag.GetPosition(etype&mask) == ENUMUNDEF ) 
			{
				if( sparse & mask )
				{
					new_tag.SetPosition(ENUMUNDEF-1,mask);
					new_tag.SetSparse(mask);
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
351
352
353
#if !defined(LAZY_SPARSE_ALLOCATION)
					need_sparse[ElementNum(mask)] = true;
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
354
355
356
				}
				else
				{
357
					INMOST_DATA_ENUM_TYPE new_pos = ENUMUNDEF;
Kirill Terekhov's avatar
Kirill Terekhov committed
358
359
360
#if defined(USE_OMP)
#pragma omp critical
#endif
361
362
363
364
365
366
367
368
369
370
					{
						new_pos = static_cast<INMOST_DATA_ENUM_TYPE>(dense_data.size());
						if( !empty_dense_data.empty() )
						{
							new_pos = empty_dense_data.back();
							empty_dense_data.pop_back();
							dense_data[new_pos] = dense_sub_type(new_tag.GetRecordSize());
						}
						else dense_data.push_back(dense_sub_type(new_tag.GetRecordSize()));
					}
Kirill Terekhov's avatar
Kirill Terekhov committed
371
					new_tag.SetPosition(new_pos,mask);
Kirill Terekhov's avatar
Kirill Terekhov committed
372
					INMOST_DATA_ENUM_TYPE new_size = dynamic_cast<Mesh *>(this)->GetArrayCapacity(ElementNum(mask));
Kirill Terekhov's avatar
Kirill Terekhov committed
373
					if( new_size < 1024 && mask != MESH ) new_size = 1024;
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
374
					if( new_size != 1   && mask == MESH ) new_size = 1;
Kirill Terekhov's avatar
Kirill Terekhov committed
375
					ReallocateData(new_tag,ElementNum(mask),new_size);
Kirill Terekhov's avatar
Kirill Terekhov committed
376
377
378
				}
			}
		}
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
379
380
381
382
383
384
385
#if !defined(LAZY_SPARSE_ALLOCATION)
		for(int j = 0; j < 6; j++) 
			if( need_sparse[j] && sparse_data[j].empty() )
			{
				INMOST_DATA_ENUM_TYPE new_size = dynamic_cast<Mesh *>(this)->GetArrayCapacity(j);
				if( new_size < 1024 && j != ElementNum(MESH) ) new_size = 1024;
				if( new_size != 1   && j == ElementNum(MESH) ) new_size = 1;
Kirill Terekhov's avatar
Kirill Terekhov committed
386
387
388
#if defined(USE_OMP)
#pragma omp critical
#endif
389
390
391
				{
					sparse_data[j].resize(new_size);
				}
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
392
393
			}
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
394
395
		return new_tag;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
396
	Tag TagManager::GetTag(std::string name) const
Kirill Terekhov's avatar
Kirill Terekhov committed
397
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
398
		for(tag_array_type::size_type i = 0; i < tags.size(); i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
399
400
			if( tags[i].GetTagName() == name )
				return tags[i];
Kirill Terekhov's avatar
Kirill Terekhov committed
401
402
		assert(false);
		return Tag();
Kirill Terekhov's avatar
Kirill Terekhov committed
403
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
404
	bool TagManager::HaveTag(std::string name) const
Kirill Terekhov's avatar
Kirill Terekhov committed
405
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
406
		for(tag_array_type::size_type i = 0; i < tags.size(); i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
407
408
409
410
411
412
413
			if( tags[i].GetTagName() == name )
				return true;
		return false;
	}
	Tag TagManager::DeleteTag(Tag tag, ElementType type_mask)
	{
		bool delete_entirely = true;
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
414
415
416
#if !defined(LAZY_SPARSE_ALLOCATION)
		bool was_sparse[6] = {false,false,false,false,false,false};
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
417
418
419
420
421
422
423
424
425
		INMOST_DATA_ENUM_TYPE tpos;//,ipos;
		for(ElementType mask = NODE; mask <= MESH; mask = mask << 1 )
		{
			tpos = tag.GetPosition(mask);
			if( tpos == ENUMUNDEF ) continue;
			if( mask & type_mask )
			{
				if( !tag.isSparse(mask) ) 
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
426
427
          //this was already done in Mesh::DeleteTag()
          //ReallocateData(tag,ElementNum(mask),0); //this should clean up the structures
Kirill Terekhov's avatar
Kirill Terekhov committed
428
429
          dense_data[tpos].clear(); //here all data should be deleted
				  empty_dense_data.push_back(tpos);
Kirill Terekhov's avatar
Kirill Terekhov committed
430
				}
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
431
432
433
#if !defined(LAZY_SPARSE_ALLOCATION)
				else was_sparse[ElementNum(mask)] = true;
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
434
435
436
437
438
439
440
				tag.SetPosition(ENUMUNDEF,mask);
			}
			else delete_entirely = false;
		}
		if( delete_entirely )
		{
			bool flag = false;
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
441
442
#if !defined(LAZY_SPARSE_ALLOCATION)
			bool have_sparse[6] = {false,false,false,false,false,false};
Kirill Terekhov's avatar
Kirill Terekhov committed
443
444
445
446
447
448
			for(int j = 0; j < 6; j++)
			{
				for(tag_array_type::size_type i = 0; i < tags.size() && !have_sparse[j]; i++)
					if( tags[i] != tag && tags[i].isSparseByDim(j) ) have_sparse[j] = true;
			}
			for(int j = 0; j < 6; j++) 
Kirill Terekhov's avatar
Kirill Terekhov committed
449
				if( was_sparse[j] && !have_sparse[j] )
Kirill Terekhov's avatar
Kirill Terekhov committed
450
			sparse_data[j].clear();
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
451
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
452
			for(tag_array_type::size_type i = 0; i < tags.size(); i++)
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
453
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
454
455
				if( tags[i] == tag )
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
456
457
				  tags.erase(tags.begin()+i);
      		flag = true;
Kirill Terekhov's avatar
Kirill Terekhov committed
458
459
					break;
				}
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
460
			}
Kirill Terekhov's avatar
Kirill Terekhov committed
461
			assert(flag);
Kirill Terekhov's avatar
Kirill Terekhov committed
462
463
464
465
466
467
468
469
470
471
472
473
474
475
			delete tag.mem;
			tag.mem = NULL;
		}
		return tag;
	}
	
	
	void TagManager::ListTagNames(std::vector<std::string> & list) const
	{
		for(tag_const_iterator it = tags.begin(); it != tags.end(); it++)
			list.push_back(it->GetTagName());
	}
		
	
Kirill Terekhov's avatar
Kirill Terekhov committed
476
	bool TagManager::ElementDefined(Tag const & tag, ElementType etype) const
Kirill Terekhov's avatar
Kirill Terekhov committed
477
478
479
480
481
	{
		INMOST_DATA_ENUM_TYPE pos = tag.GetPosition(etype);
		if( pos == ENUMUNDEF ) return false;
		return true;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
482

Kirill Terekhov's avatar
Kirill Terekhov committed
483
	void TagManager::ReallocateData(INMOST_DATA_INTEGER_TYPE etypenum, INMOST_DATA_ENUM_TYPE new_size)
Kirill Terekhov's avatar
Kirill Terekhov committed
484
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
485
486
		if( new_size < 1024 && etypenum != ElementNum(MESH) ) new_size = 1024;
		if( new_size != 1   && etypenum == ElementNum(MESH) ) new_size = 1;
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
487
488
489
490
491
492
493
494
		if( back_links [etypenum].size() != new_size ) 
			back_links [etypenum].resize(new_size,-1);
#if defined(LAZY_SPARSE_ALLOCATION)
		if( sparse_data[etypenum].size() != new_size ) 
			sparse_data[etypenum].resize(new_size);
#else
		bool need_sparse = false;
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
495
		for(iteratorTag t = tags.begin(); t != tags.end(); ++t)
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
496
		{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
497
			if( t->isDefinedByDim(etypenum) ) 
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
498
			{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
499
				if( !t->isSparseByDim(etypenum) ) 
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
					ReallocateData(*t,etypenum,new_size);
#if !defined(LAZY_SPARSE_ALLOCATION)
				else 
					need_sparse = true;
#endif
			}
		}
#if !defined(LAZY_SPARSE_ALLOCATION)
		if( need_sparse )
		{
			if( sparse_data[etypenum].size() != new_size ) 
				sparse_data[etypenum].resize(new_size);
		}
		else if( !sparse_data[etypenum].empty() )
		{
			sparse_data[etypenum].clear();
		}
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
518
519
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
520
	void TagManager::ReallocateData(const Tag & t, INMOST_DATA_INTEGER_TYPE etypenum, INMOST_DATA_ENUM_TYPE new_size)
Kirill Terekhov's avatar
Kirill Terekhov committed
521
	{
Kirill Terekhov's avatar
Fixes    
Kirill Terekhov committed
522
		INMOST_DATA_ENUM_TYPE        data_pos    = t.GetPositionByDim(etypenum);
Kirill Terekhov's avatar
Kirill Terekhov committed
523
524
525
526
		INMOST_DATA_ENUM_TYPE        data_size   = t.GetSize();
		TagManager::dense_sub_type & arr         = GetDenseData(data_pos);
		INMOST_DATA_ENUM_TYPE        old_size    = static_cast<INMOST_DATA_ENUM_TYPE>(arr.size());
		DataType                     data_type   = t.GetDataType();
Kirill Terekhov's avatar
Kirill Terekhov committed
527
528
		if( data_size == ENUMUNDEF )
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
529
			if( new_size < old_size )
Kirill Terekhov's avatar
Kirill Terekhov committed
530
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
531
				switch(data_type)
Kirill Terekhov's avatar
Kirill Terekhov committed
532
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
533
534
535
536
					case DATA_REAL:      for(INMOST_DATA_ENUM_TYPE it = new_size; it < old_size; ++it) {void * p = static_cast<void *>(&arr[it]); if( p != NULL ) (*static_cast<inner_real_array      *>( p )).~inner_real_array();     } break;
					case DATA_INTEGER:   for(INMOST_DATA_ENUM_TYPE it = new_size; it < old_size; ++it) {void * p = static_cast<void *>(&arr[it]); if( p != NULL ) (*static_cast<inner_integer_array   *>( p )).~inner_integer_array();  } break;
					case DATA_BULK:      for(INMOST_DATA_ENUM_TYPE it = new_size; it < old_size; ++it) {void * p = static_cast<void *>(&arr[it]); if( p != NULL ) (*static_cast<inner_bulk_array      *>( p )).~inner_bulk_array();     } break;
					case DATA_REFERENCE: for(INMOST_DATA_ENUM_TYPE it = new_size; it < old_size; ++it) {void * p = static_cast<void *>(&arr[it]); if( p != NULL ) (*static_cast<inner_reference_array *>( p )).~inner_reference_array();} break;
Kirill Terekhov's avatar
Kirill Terekhov committed
537
538
					case DATA_REMOTE_REFERENCE: 
										 for(INMOST_DATA_ENUM_TYPE it = new_size; it < old_size; ++it) {void * p = static_cast<void *>(&arr[it]); if( p != NULL ) (*static_cast<inner_remote_reference_array *>( p )).~inner_remote_reference_array();} break;
539
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
540
					case DATA_VARIABLE:  for(INMOST_DATA_ENUM_TYPE it = new_size; it < old_size; ++it) {void * p = static_cast<void *>(&arr[it]); if( p != NULL ) (*static_cast<inner_variable_array  *>( p )).~inner_variable_array(); } break;
541
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
542
543
544
				}
			}
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
545
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
546
547
548
549
550
551
552
553
554
		else if( data_type == DATA_VARIABLE ) //Have to perform in-memory deallocation to correctly remove class inheritance
		{
			for(INMOST_DATA_ENUM_TYPE it = new_size; it < old_size; ++it) 
			{
				variable * p = static_cast<variable *>(static_cast<void *>(&arr[it]));
				for(INMOST_DATA_ENUM_TYPE jt = 0; jt < data_size; ++jt)
					p[jt].~variable();
			}
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
555
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
556
557
558
#if defined(USE_OMP)
#pragma omp critical
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
559
560
561
		{
			arr.resize(new_size);
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
562
		if(  data_size == ENUMUNDEF ) //Initialize variable-sized data
Kirill Terekhov's avatar
Kirill Terekhov committed
563
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
564
			switch(data_type)
Kirill Terekhov's avatar
Kirill Terekhov committed
565
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
566
567
568
569
				case DATA_REAL:      for(INMOST_DATA_ENUM_TYPE it = old_size; it < new_size; ++it) new ( &arr[it] ) inner_real_array();      break;
				case DATA_INTEGER:   for(INMOST_DATA_ENUM_TYPE it = old_size; it < new_size; ++it) new ( &arr[it] ) inner_integer_array();   break;
				case DATA_BULK:      for(INMOST_DATA_ENUM_TYPE it = old_size; it < new_size; ++it) new ( &arr[it] ) inner_bulk_array();      break;
				case DATA_REFERENCE: for(INMOST_DATA_ENUM_TYPE it = old_size; it < new_size; ++it) new ( &arr[it] ) inner_reference_array(); break;
Kirill Terekhov's avatar
Kirill Terekhov committed
570
571
				case DATA_REMOTE_REFERENCE: 
									 for(INMOST_DATA_ENUM_TYPE it = old_size; it < new_size; ++it) new ( &arr[it] ) inner_remote_reference_array(); break;
572
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
573
				case DATA_VARIABLE:  for(INMOST_DATA_ENUM_TYPE it = old_size; it < new_size; ++it) new ( &arr[it] ) inner_variable_array();  break;
574
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
575
576
			}
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
577
#if defined(USE_AUTODIFF)
Kirill Terekhov's avatar
Kirill Terekhov committed
578
579
580
581
582
583
584
585
586
		else if( data_type == DATA_VARIABLE ) //Have to perform in-memory allocation to correctly setup class inheritance
		{
			for(INMOST_DATA_ENUM_TYPE it = old_size; it < new_size; ++it) 
			{
				variable * p = static_cast<variable *>(static_cast<void *>(&arr[it]));
				for(INMOST_DATA_ENUM_TYPE jt = 0; jt < data_size; ++jt)
					new (p+jt) variable();
			}
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
587
#endif
Kirill Terekhov's avatar
Kirill Terekhov committed
588
589
590
591
	}
	
}
#endif