tag.cpp 13.3 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 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
	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";
		}
		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);
			case DATA_REFERENCE: return sizeof(HandleType);
		}
		return 0;
	}


	__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);
		}
		return 0;
	}


	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();
		if( data_size == ENUMUNDEF ) //variable size array
		{
			DataType type = t.GetDataType();
			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));
		}
		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
90 91 92 93 94 95 96 97
	
	TagMemory::TagMemory(Mesh * m, const TagMemory & other)
	{
		for(int i = 0; i < __NET; i++)
		{
			pos[i]	= other.pos[i];
			sparse[i] = other.sparse[i];
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
98 99
		tagname		   = other.tagname;
		dtype		   = other.dtype;
Kirill Terekhov's avatar
Kirill Terekhov committed
100
		bulk_data_type = other.bulk_data_type;
Kirill Terekhov's avatar
Kirill Terekhov committed
101 102 103 104
		m_link         = m;
		size           = other.size;
		record_size    = other.record_size;
		bytes_size     = other.bytes_size;
Kirill Terekhov's avatar
Kirill Terekhov committed
105 106 107 108 109 110
	}
	
	TagMemory & TagMemory::operator =(TagMemory const & other)
	{
		for(int i = 0; i < __NET; i++)
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
111 112
			pos[i]      = other.pos[i];
			sparse[i]   = other.sparse[i];
Kirill Terekhov's avatar
Kirill Terekhov committed
113 114 115
		}
		tagname         = other.tagname;
		dtype           = other.dtype;
Kirill Terekhov's avatar
Kirill Terekhov committed
116 117 118 119 120
		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;
Kirill Terekhov's avatar
Kirill Terekhov committed
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 147 148 149 150 151 152 153 154 155 156
		return *this;	
	}
	
	
	TagMemory::~TagMemory()
	{
	}
	
	TagMemory::TagMemory()
	{
		for(int i = 0; i < __NET; i++)
		{
			pos[i]	= ENUMUNDEF;
			sparse[i] = false;
		}
		tagname = "";
	}
	
	Tag::Tag(Mesh * m, std::string name, DataType _dtype,INMOST_DATA_ENUM_TYPE size)
	{
		mem = new TagMemory();
		for(int i = 0; i < __NET; i++)
		{
			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;
			case DATA_REFERENCE: mem->bulk_data_type = INMOST_MPI_DATA_ENUM_TYPE; break;
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
157
		mem->bytes_size = DataTypeBytesSize(mem->dtype);
Kirill Terekhov's avatar
Kirill Terekhov committed
158 159 160
		if(mem->size == ENUMUNDEF )
			mem->record_size = VariableDataSize(mem->dtype);
		else
Kirill Terekhov's avatar
Kirill Terekhov committed
161
			mem->record_size = mem->size * mem->bytes_size;
Kirill Terekhov's avatar
Kirill Terekhov committed
162 163
		mem->m_link = m;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
164
	TagManager::TagManager()
Kirill Terekhov's avatar
Kirill Terekhov committed
165 166
	{
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
167
	TagManager::TagManager(const TagManager & other)
Kirill Terekhov's avatar
Kirill Terekhov committed
168 169
	{
		tags.resize(other.tags.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
170
		dense_data.resize(other.dense_data.size(),dense_sub_type(0));
Kirill Terekhov's avatar
Kirill Terekhov committed
171
		for(tag_array_type::size_type i = 0; i < other.tags.size(); i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
172
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
173
			tags[i].mem = new TagMemory(dynamic_cast<Mesh *>(this),*other.tags[i].mem);
Kirill Terekhov's avatar
Kirill Terekhov committed
174 175
			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
176 177 178 179
				{
					dense_data[tags[i].GetPosition(etype)] = dense_sub_type(tags[i].GetRecordSize());
					//tags[i].AllocateData(etype);
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
180
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
181
		
Kirill Terekhov's avatar
Kirill Terekhov committed
182 183 184 185
		//The rest of the data should be allocated and copied while copying data of
		//individual elements
	}

Kirill Terekhov's avatar
Kirill Terekhov committed
186
	TagManager & TagManager::operator =(TagManager const & other)
Kirill Terekhov's avatar
Kirill Terekhov committed
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
	{

		//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
208
		dense_data.clear();
Kirill Terekhov's avatar
Kirill Terekhov committed
209 210
		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
211
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
212
			tags[i].mem = new TagMemory(dynamic_cast<Mesh *>(this),*other.tags[i].mem);
Kirill Terekhov's avatar
Kirill Terekhov committed
213 214
			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
215 216 217 218
				{
					dense_data[tags[i].GetPosition(etype)] = dense_sub_type(tags[i].GetRecordSize());
					//tags[i].AllocateData(etype);
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
219
		}
Kirill Terekhov's avatar
Kirill Terekhov committed
220 221
		for(int i = 0; i < 6; i++)
			sparse_data[i].clear();
Kirill Terekhov's avatar
Kirill Terekhov committed
222 223 224 225 226 227 228 229
		//~ 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
230 231
		dense_data.clear();
		for(int i = 0; i < 6; i++) sparse_data[i].clear();
Kirill Terekhov's avatar
Kirill Terekhov committed
232 233 234 235 236 237 238 239 240
		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
Kirill Terekhov committed
241
		for(tag_array_type::size_type i = 0; i < tags.size(); i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
242 243
			if( tags[i].GetTagName() == name )
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
244 245 246 247 248
				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
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
				new_tag = tags[i];
				break;
			}
		if( !new_tag.isValid() )
		{
			new_tag = Tag(m,name,dtype,size);
			tags.push_back(new_tag);
		}
		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);
				}
				else
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
268
					INMOST_DATA_ENUM_TYPE new_pos = static_cast<INMOST_DATA_ENUM_TYPE>(dense_data.size());
Kirill Terekhov's avatar
Kirill Terekhov committed
269 270 271 272
					if( !empty_dense_data.empty() )
					{
						new_pos = empty_dense_data.back();
						empty_dense_data.pop_back();
Kirill Terekhov's avatar
Kirill Terekhov committed
273
						dense_data[new_pos] = dense_sub_type(new_tag.GetRecordSize());
Kirill Terekhov's avatar
Kirill Terekhov committed
274
					}
Kirill Terekhov's avatar
Kirill Terekhov committed
275
					else dense_data.push_back(dense_sub_type(new_tag.GetRecordSize()));
Kirill Terekhov's avatar
Kirill Terekhov committed
276
					new_tag.SetPosition(new_pos,mask);
Kirill Terekhov's avatar
Kirill Terekhov committed
277
					INMOST_DATA_ENUM_TYPE new_size = dynamic_cast<Mesh *>(this)->GetArrayCapacity(ElementNum(mask));
Kirill Terekhov's avatar
Kirill Terekhov committed
278 279
					if( new_size < 1024 && mask != MESH ) new_size = 1024;
					if( new_size < 1    && mask == MESH ) new_size = 1;
Kirill Terekhov's avatar
Kirill Terekhov committed
280
					ReallocateData(new_tag,ElementNum(mask),new_size);
Kirill Terekhov's avatar
Kirill Terekhov committed
281 282 283 284 285 286 287
				}
			}
		}
		
		
		return new_tag;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
288
	Tag TagManager::GetTag(std::string name) const
Kirill Terekhov's avatar
Kirill Terekhov committed
289
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
290
		for(tag_array_type::size_type i = 0; i < tags.size(); i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
291 292
			if( tags[i].GetTagName() == name )
				return tags[i];
Kirill Terekhov's avatar
Kirill Terekhov committed
293 294
		assert(false);
		return Tag();
Kirill Terekhov's avatar
Kirill Terekhov committed
295
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
296
	bool TagManager::HaveTag(std::string name) const
Kirill Terekhov's avatar
Kirill Terekhov committed
297
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
298
		for(tag_array_type::size_type i = 0; i < tags.size(); i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
			if( tags[i].GetTagName() == name )
				return true;
		return false;
	}
	Tag TagManager::DeleteTag(Tag tag, ElementType type_mask)
	{
		bool delete_entirely = true;
		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) ) 
				{
					dense_data[tpos].clear(); //here all data should be deleted
					empty_dense_data.push_back(tpos);
				}
				tag.SetPosition(ENUMUNDEF,mask);
			}
			else delete_entirely = false;
		}
		if( delete_entirely )
		{
			bool flag = false;
Kirill Terekhov's avatar
Kirill Terekhov committed
325
			for(tag_array_type::size_type i = 0; i < tags.size(); i++)
Kirill Terekhov's avatar
Kirill Terekhov committed
326 327 328 329 330 331
				if( tags[i] == tag )
				{
					tags.erase(tags.begin()+i);
					flag = true;
					break;
				}
Kirill Terekhov's avatar
Kirill Terekhov committed
332
			assert(flag);
Kirill Terekhov's avatar
Kirill Terekhov committed
333 334 335 336 337 338 339 340 341 342 343 344 345 346
			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
347
	bool TagManager::ElementDefined(Tag const & tag, ElementType etype) const
Kirill Terekhov's avatar
Kirill Terekhov committed
348 349 350 351 352
	{
		INMOST_DATA_ENUM_TYPE pos = tag.GetPosition(etype);
		if( pos == ENUMUNDEF ) return false;
		return true;
	}
Kirill Terekhov's avatar
Kirill Terekhov committed
353

Kirill Terekhov's avatar
Kirill Terekhov committed
354
	void TagManager::ReallocateData(INMOST_DATA_INTEGER_TYPE etypenum, INMOST_DATA_ENUM_TYPE new_size)
Kirill Terekhov's avatar
Kirill Terekhov committed
355
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
356 357 358 359 360 361
		if( new_size < 1024 && etypenum != ElementNum(MESH) ) new_size = 1024;
		if( new_size != 1   && etypenum == ElementNum(MESH) ) new_size = 1;
		sparse_data[etypenum].resize(new_size);
		back_links[etypenum].resize(new_size,ENUMUNDEF);
		for(iteratorTag t = tags.begin(); t != tags.end(); ++t)
			if( t->isDefined(1 << etypenum) && !t->isSparse(1 << etypenum) ) ReallocateData(*t,etypenum,new_size);
Kirill Terekhov's avatar
Kirill Terekhov committed
362 363
	}
	
Kirill Terekhov's avatar
Kirill Terekhov committed
364
	void TagManager::ReallocateData(const Tag & t, INMOST_DATA_INTEGER_TYPE etypenum, INMOST_DATA_ENUM_TYPE new_size)
Kirill Terekhov's avatar
Kirill Terekhov committed
365
	{
Kirill Terekhov's avatar
Kirill Terekhov committed
366 367 368 369 370
		INMOST_DATA_ENUM_TYPE        data_pos    = t.GetPositionNum(etypenum);
		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
371 372
		if( data_size == ENUMUNDEF )
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
373
			if( new_size < old_size )
Kirill Terekhov's avatar
Kirill Terekhov committed
374
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
375
				switch(data_type)
Kirill Terekhov's avatar
Kirill Terekhov committed
376
				{
Kirill Terekhov's avatar
Kirill Terekhov committed
377 378 379 380
					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
381 382 383 384
				}
			}
		}
		arr.resize(new_size);
Kirill Terekhov's avatar
Kirill Terekhov committed
385
		if(  data_size == ENUMUNDEF ) //Initialize variable-sized data
Kirill Terekhov's avatar
Kirill Terekhov committed
386
		{
Kirill Terekhov's avatar
Kirill Terekhov committed
387
			switch(data_type)
Kirill Terekhov's avatar
Kirill Terekhov committed
388
			{
Kirill Terekhov's avatar
Kirill Terekhov committed
389 390 391 392
				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
393 394 395 396 397 398 399 400 401
			}
		}
	}
	
	
	
	
}
#endif