Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

attributeContainer.cpp 24.1 KB
Newer Older
1
2
3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                           *
21
22
23
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
24
25
26
27
28
29
30
31

#include <typeinfo>
#include <stdio.h>
#include <string.h>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
#include <iostream>

32
#include "Container/attributeContainer.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
33
34
35
36

namespace CGoGN
{

37
AttributeContainer::AttributeContainer() :
38
	m_currentBrowser(NULL),
39
40
41
42
43
44
45
	m_orbit(0),
	m_nbAttributes(0),
	m_nbUnknown(0),
	m_size(0),
	m_maxSize(0),
	m_lineCost(0),
	m_attributes_registry_map(NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
46
47
48
49
{
	m_holesBlocks.reserve(512);
}

50
AttributeContainer::~AttributeContainer()
Pierre Kraemer's avatar
Pierre Kraemer committed
51
{
52
53
54
55
56
57
58
59
60
61
62
63
	for (unsigned int index = 0; index < m_tableAttribs.size(); ++index)
	{
		if (m_tableAttribs[index] != NULL)
			delete m_tableAttribs[index];
	}

	for (unsigned int index = 0; index < m_holesBlocks.size(); ++index)
	{
		if (m_holesBlocks[index] != NULL)
			delete m_holesBlocks[index];
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
64
65
}

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**************************************
 *       INFO ABOUT ATTRIBUTES        *
 **************************************/

unsigned int AttributeContainer::getAttributeIndex(const std::string& attribName)
{
	unsigned int index ;
	bool found = false ;
	for (index = 0; index < m_tableAttribs.size() && !found; ++index)
	{
		if(m_tableAttribs[index] != NULL && m_tableAttribs[index]->getName() == attribName)
			found = true ;
	}

	if (!found)
		return UNKNOWN;
	else
		return index - 1 ;
}

86
const std::string& AttributeContainer::getAttributeName(unsigned int index) const
87
88
89
90
{
	assert(index < m_tableAttribs.size() || !"getAttributeName: attribute index out of bounds");
	assert(m_tableAttribs[index] != NULL || !"getAttributeName: attribute does not exist");

91
	return m_tableAttribs[index]->getName() ;
92
93
94
95
96
97
98
99
100
101
102
103
104
}

template <typename T>
unsigned int AttributeContainer::getAttributeBlocksPointers(unsigned int attrIndex, std::vector<T*>& vect_ptr, unsigned int& byteBlockSize)
{
	assert(attrIndex < m_tableAttribs.size() || !"getAttributeBlocksPointers: attribute index out of bounds");
	assert(m_tableAttribs[attrIndex] != NULL || !"getAttributeBlocksPointers: attribute does not exist");

	AttributeMultiVector<T>* atm = dynamic_cast<AttributeMultiVector<T>*>(m_tableAttribs[attrIndex]);
	assert((atm != NULL) || !"getAttributeBlocksPointers: wrong type");
	return atm->getBlocksPointers(vect_ptr, byteBlockSize);
}

105
unsigned int AttributeContainer::getAttributesNames(std::vector<std::string>& names) const
106
107
108
109
110
111
112
113
114
115
116
117
118
{
	names.clear() ;
	names.reserve(m_nbAttributes) ;

	for (unsigned int i = 0; i < m_tableAttribs.size(); ++i)
	{
		if(m_tableAttribs[i] != NULL)
			names.push_back(m_tableAttribs[i]->getName()) ;
	}

	return m_nbAttributes ;
}

Sylvain Thery's avatar
Sylvain Thery committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
unsigned int AttributeContainer::getAttributesTypes(std::vector<std::string>& types)
{
	types.clear() ;
	types.reserve(m_nbAttributes) ;

	for (unsigned int i = 0; i < m_tableAttribs.size(); ++i)
	{
		if(m_tableAttribs[i] != NULL)
			types.push_back(m_tableAttribs[i]->getTypeName()) ;
	}

	return m_nbAttributes ;
}

133
134
135
136
/**************************************
 *        CONTAINER MANAGEMENT        *
 **************************************/

137
void AttributeContainer::swap(AttributeContainer& cont)
Pierre Kraemer's avatar
Pierre Kraemer committed
138
{
139
140
	// swap everything but the orbit

Pierre Kraemer's avatar
Pierre Kraemer committed
141
	m_tableAttribs.swap(cont.m_tableAttribs);
Pierre Kraemer's avatar
Pierre Kraemer committed
142
	m_freeIndices.swap(cont.m_freeIndices);
143
144
145
	m_holesBlocks.swap(cont.m_holesBlocks);
	m_tableBlocksWithFree.swap(cont.m_tableBlocksWithFree);
	m_tableBlocksEmpty.swap(cont.m_tableBlocksEmpty);
Pierre Kraemer's avatar
Pierre Kraemer committed
146
147
148
149
150

	unsigned int temp = m_nbAttributes;
	m_nbAttributes = cont.m_nbAttributes;
	cont.m_nbAttributes = temp;

151
152
153
154
	temp = m_nbUnknown ;
	m_nbUnknown = cont.m_nbUnknown ;
	cont.m_nbUnknown = temp ;

Pierre Kraemer's avatar
Pierre Kraemer committed
155
156
157
158
159
160
161
162
163
164
165
166
167
	temp = m_size;
	m_size = cont.m_size;
	cont.m_size = temp;

	temp = m_maxSize;
	m_maxSize = cont.m_maxSize;
	cont.m_maxSize = temp;

	temp = m_lineCost;
	m_lineCost = cont.m_lineCost;
	cont.m_lineCost = temp;
}

168
void AttributeContainer::clear(bool removeAttrib)
Pierre Kraemer's avatar
Pierre Kraemer committed
169
{
170
171
	m_size = 0;
 	m_maxSize = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
172

173
		// raz des cases libres
174
175
	for (std::vector<HoleBlockRef*>::iterator it = m_holesBlocks.begin(); it != m_holesBlocks.end(); ++it)
		delete (*it);
Pierre Kraemer's avatar
Pierre Kraemer committed
176

Sylvain Thery's avatar
Sylvain Thery committed
177
178
179
	{ // add bracket just for scope of temporary vectors
		std::vector<HoleBlockRef*> bf;
		m_holesBlocks.swap(bf);
180

Sylvain Thery's avatar
Sylvain Thery committed
181
182
183
		std::vector<unsigned int> bwf;
		m_tableBlocksWithFree.swap(bwf);
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
184

185
186
187
188
189
190
	// detruit les données
	for (std::vector<AttributeMultiVectorGen*>::iterator it = m_tableAttribs.begin(); it != m_tableAttribs.end(); ++it)
	{
		if ((*it) != NULL)
			(*it)->clear();
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
191

192
193
194
195
196
197
198
199
200
201
202
203
	// on enleve les attributs ?
	if (removeAttrib)
	{
		// nb a zero
		m_nbAttributes = 0;

		// detruit tous les attributs
		for (std::vector<AttributeMultiVectorGen*>::iterator it = m_tableAttribs.begin(); it != m_tableAttribs.end(); ++it)
		{
			if ((*it) != NULL)
				delete (*it);
		}
204
205

		std::vector<AttributeMultiVectorGen*> amg;
206
		m_tableAttribs.swap(amg);
207
208
209

		std::vector<unsigned int> fi;
		m_freeIndices.swap(fi);
210
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
211
212
}

213
void AttributeContainer::compact(std::vector<unsigned int>& mapOldNew)
Pierre Kraemer's avatar
Pierre Kraemer committed
214
{
215
	unsigned int nbe = _BLOCKSIZE_ * m_holesBlocks.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
216

217
218
219
220
221
222
223
	unsigned int nbb = m_holesBlocks.size() - 1;
	while ((m_holesBlocks[nbb])->empty())
	{
		--nbb;
		nbe -= _BLOCKSIZE_;
	}
	++nbb;
Pierre Kraemer's avatar
Pierre Kraemer committed
224

225
	mapOldNew.clear();
226
	mapOldNew.reserve(nbe);
Pierre Kraemer's avatar
Pierre Kraemer committed
227

228
229
230
231
232
	// now get the holes
	unsigned int baseAdr = 0;
	for (unsigned int i = 0; i < nbb; ++i)
	{
		HoleBlockRef* block = m_holesBlocks[i];
Pierre Kraemer's avatar
Pierre Kraemer committed
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
		for (unsigned int j = 0; j < _BLOCKSIZE_; ++j)
		{
			if (j < block->sizeTable())
			{
				if (block->used(j))
					mapOldNew.push_back(baseAdr);
				else
					mapOldNew.push_back(0xffffffff);
			}
			else
				mapOldNew.push_back(0xffffffff);
			baseAdr++;
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
248

249
	unsigned int last = mapOldNew.size() - 1;
Pierre Kraemer's avatar
Pierre Kraemer committed
250

251
252
253
254
255
256
257
258
 	for (unsigned int i = 0 ; i < last; ++i)
	{
		unsigned int val = mapOldNew[i];
		if (val == 0xffffffff)
		{
			// first find last element
			while (mapOldNew[last] == 0xffffffff)
				--last;
Pierre Kraemer's avatar
Pierre Kraemer committed
259

260
261
262
263
264
265
			// store it in the hole
			// find the blocks and indices
			unsigned int bi = i / _BLOCKSIZE_;
			unsigned int ib = i % _BLOCKSIZE_;
			unsigned int bj = last / _BLOCKSIZE_;
			unsigned int jb = last % _BLOCKSIZE_;
Pierre Kraemer's avatar
Pierre Kraemer committed
266

267
268
269
270
271
272
			//overwrite attributes
			for(unsigned int j = 0; j < m_tableAttribs.size(); ++j)
			{
				if (m_tableAttribs[j] != NULL)
					m_tableAttribs[j]->overwrite(bj, jb, bi, ib);
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
273

274
275
			// overwrite emptyLine with last line in free blocks
			m_holesBlocks[bi]->overwrite(ib, m_holesBlocks[bj], jb);
Pierre Kraemer's avatar
Pierre Kraemer committed
276

277
278
279
			// set the map value
			mapOldNew[last] = i;
			--last;
Pierre Kraemer's avatar
Pierre Kraemer committed
280
281
282
		}
	}

283
	for (int i = m_holesBlocks.size() - 1; i >= 0; --i)
Pierre Kraemer's avatar
Pierre Kraemer committed
284
	{
285
286
		HoleBlockRef* ptr = m_holesBlocks[i];
		if (ptr->compressFree())
Pierre Kraemer's avatar
Pierre Kraemer committed
287
		{
288
289
			delete ptr;
			m_holesBlocks.pop_back();
Pierre Kraemer's avatar
Pierre Kraemer committed
290
291
292
		}
	}

293
294
295
296
297
298
299
300
	// maj de la table de block libre
	m_tableBlocksWithFree.clear();
	HoleBlockRef* block = m_holesBlocks.back();
	if (!block->full())
		m_tableBlocksWithFree.push_back(m_holesBlocks.size() - 1);

	// detruit les blocks de donnees inutiles
	for(unsigned int j = 0; j < m_tableAttribs.size(); ++j)
Pierre Kraemer's avatar
Pierre Kraemer committed
301
	{
302
303
		if (m_tableAttribs[j] != NULL)
			m_tableAttribs[j]->setNbBlocks(m_holesBlocks.size());
Pierre Kraemer's avatar
Pierre Kraemer committed
304
305
	}

306
307
308
309
310
311
	m_maxSize = (m_holesBlocks.back())->sizeTable() + (m_holesBlocks.size() - 1) * _BLOCKSIZE_;
}

/**************************************
 *          LINES MANAGEMENT          *
 **************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
312

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
//unsigned int AttributeContainer::insertLine()
//{
//	// if no more rooms
//	if (m_tableBlocksWithFree.empty())
//	{
//		HoleBlockRef* ptr = new HoleBlockRef();					// new block
//		m_tableBlocksWithFree.push_back(m_holesBlocks.size());	// add its future position to block_free
//		m_holesBlocks.push_back(ptr);							// and add it to block table

//		for(unsigned int i = 0; i < m_tableAttribs.size(); ++i)
//		{
//			if (m_tableAttribs[i] != NULL)
//				m_tableAttribs[i]->addBlock();					// add a block to every attribute
//		}
//	}

//	// get the first free block index (last in vector)
//	unsigned int bf = m_tableBlocksWithFree.back();
//	// get the block
//	HoleBlockRef* block = m_holesBlocks[bf];

//	// add new element in block and compute index
//	unsigned int ne = block->newRefElt(m_maxSize);
//	unsigned int index = _BLOCKSIZE_ * bf + ne;

//	// if no more room in block remove it from free_blocks
//	if (block->full())
//		m_tableBlocksWithFree.pop_back();

//	++m_size;

////	initLine(index);

//	return index;
//}


350
351
352
353
unsigned int AttributeContainer::insertLine()
{
	// if no more rooms
	if (m_tableBlocksWithFree.empty())
Pierre Kraemer's avatar
Pierre Kraemer committed
354
	{
355
		HoleBlockRef* ptr = new HoleBlockRef();					// new block
356
357
		unsigned int numBlock = m_holesBlocks.size();
		m_tableBlocksWithFree.push_back(numBlock);	// add its future position to block_free
358
359
360
361
362
363
364
		m_holesBlocks.push_back(ptr);							// and add it to block table

		for(unsigned int i = 0; i < m_tableAttribs.size(); ++i)
		{
			if (m_tableAttribs[i] != NULL)
				m_tableAttribs[i]->addBlock();					// add a block to every attribute
		}
365
366
367
368
369
370
371
372

		// inc nb of elements
		++m_size;

		// add new element in block and compute index

		unsigned int ne = ptr->newRefElt(m_maxSize);
		return _BLOCKSIZE_ * numBlock + ne;
Pierre Kraemer's avatar
Pierre Kraemer committed
373
	}
374
	// else
Pierre Kraemer's avatar
Pierre Kraemer committed
375

376
377
378
379
380
381
382
383
384
	// get the first free block index (last in vector)
	unsigned int bf = m_tableBlocksWithFree.back();
	// get the block
	HoleBlockRef* block = m_holesBlocks[bf];

	// add new element in block and compute index
	unsigned int ne = block->newRefElt(m_maxSize);
	unsigned int index = _BLOCKSIZE_ * bf + ne;

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
	if (ne == _BLOCKSIZE_-1)
	{
		if (bf == (m_holesBlocks.size()-1))
		{
			// we are filling the last line of capacity
			HoleBlockRef* ptr = new HoleBlockRef();					// new block
			unsigned int numBlock = m_holesBlocks.size();
			m_tableBlocksWithFree.back() = numBlock;
			m_tableBlocksWithFree.push_back(bf);
			m_holesBlocks.push_back(ptr);

			for(unsigned int i = 0; i < m_tableAttribs.size(); ++i)
			{
				if (m_tableAttribs[i] != NULL)
					m_tableAttribs[i]->addBlock();					// add a block to every attribute
			}
		}
	}

404
405
406
407
408
409
	// if no more room in block remove it from free_blocks
	if (block->full())
		m_tableBlocksWithFree.pop_back();

	++m_size;
	return index;
Pierre Kraemer's avatar
Pierre Kraemer committed
410
411
}

412

413
void AttributeContainer::removeLine(unsigned int index)
Pierre Kraemer's avatar
Pierre Kraemer committed
414
{
415
416
	unsigned int bi = index / _BLOCKSIZE_;
	unsigned int j = index % _BLOCKSIZE_;
Pierre Kraemer's avatar
Pierre Kraemer committed
417

418
	HoleBlockRef* block = m_holesBlocks[bi];
Pierre Kraemer's avatar
Pierre Kraemer committed
419

420
421
422
423
	if (block->used(j))
	{
		if (block->full())		// block has no free elements before removal
			m_tableBlocksWithFree.push_back(bi);
Pierre Kraemer's avatar
Pierre Kraemer committed
424

425
		block->removeElt(j);
Pierre Kraemer's avatar
Pierre Kraemer committed
426

427
		--m_size;
Pierre Kraemer's avatar
Pierre Kraemer committed
428

429
430
		if (block->empty())		// block is empty after removal
			m_tableBlocksEmpty.push_back(bi);
Pierre Kraemer's avatar
Pierre Kraemer committed
431
	}
432
	else
433
		CGoGNerr << "Error removing non existing index " << index << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
434
435
}

436
437
438
/**************************************
 *            SAVE & LOAD             *
 **************************************/
Sylvain Thery's avatar
Sylvain Thery committed
439
440
441
442
//
//bool AttributeContainer::loadXmlBWF(xmlNodePtr node)
//{
//	xmlChar* prop = xmlGetProp(node, BAD_CAST "nb");
Pierre Kraemer's avatar
Pierre Kraemer committed
443
//	unsigned int nb = atoi((char*)prop);
Sylvain Thery's avatar
Sylvain Thery committed
444
445
446
447
448
449
450
451
452
//	m_tableBlocksWithFree.clear();
//
//	// charge et cree les  attributs
//	for (xmlNode* x_node = node->children; x_node != NULL; x_node = x_node->next)
//	{
//		unsigned int ind = atoi((char*)(xmlNodeGetContent(x_node)));
//		m_tableBlocksWithFree.push_back(ind);
//	}
//	if (m_tableBlocksWithFree.size() != nb)
Pierre Kraemer's avatar
Pierre Kraemer committed
453
//	{
Sylvain Thery's avatar
Sylvain Thery committed
454
//		CGoGNerr <<"Erreur lecture fichier XML incoherent"<< CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
455
456
//		return false;
//	}
Sylvain Thery's avatar
Sylvain Thery committed
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
//	return true;
//}
//
//bool AttributeContainer::loadXmlAN(xmlNodePtr node, unsigned int nbb)
//{
//	xmlChar* prop = xmlGetProp(node, BAD_CAST "nb");
////	unsigned int nb = atoi((char*)prop);
//	prop = xmlGetProp(node, BAD_CAST "sv");
////	unsigned int sv = atoi((char*)prop);
//
//	// Noooooooo!!!!
////	m_tableAttribs.resize(sv);
////	for (unsigned int i=0; i< sv; ++i)
////			m_tableAttribs[i]=NULL;
//
//	// charge et cree les  attributs
//	for (xmlNode* x_node = node->children; x_node != NULL; x_node = x_node->next)
//	{
//		prop = xmlGetProp(x_node, BAD_CAST "id");
////		unsigned int id = unsigned int(atoi((char*)prop);
//
//		prop = xmlGetProp(x_node, BAD_CAST "type");
//		// recupere l'attribut enregistrer par son type
//		if (m_attributes_registry_map !=NULL)
//		{
//			std::map<std::string, RegisteredBaseAttribute*>::iterator itAtt = m_attributes_registry_map->find(std::string((char*)prop));
//			if (itAtt == m_attributes_registry_map->end())
484
//			{
Sylvain Thery's avatar
Sylvain Thery committed
485
//				CGoGNout << "Skipping non registred attribute "<< std::string((char*)prop)<<CGoGNendl;
486
//			}
Sylvain Thery's avatar
Sylvain Thery committed
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
//			else
//			{
//				RegisteredBaseAttribute* ra = itAtt->second;
//				prop = xmlGetProp(x_node, BAD_CAST "name");
////				ra->addAttribute(*this, std::string((char*)prop), id);
//				AttributeMultiVectorGen* amvg = ra->addAttribute(*this, std::string((char*)prop));
//				amvg->setNbBlocks(nbb);
//			}
//		}
//		else
//		{
//			CGoGNerr << "Attribute Registry non initialized"<< CGoGNendl;
//			return false;
//		}
//	}
////	if (m_attribNameMap.size() != nb)
////	{
////		CGoGNerr << "Pb lecture attributs"<< CGoGNendl;
////		return false;
////	}
//	return true;
//}
//
//bool AttributeContainer::loadXmlDL(xmlNodePtr node)
//{
//	// charge et cree les  attributs
//	for (xmlNode* x_node = node->children; x_node != NULL; x_node = x_node->next)
514
//	{
Sylvain Thery's avatar
Sylvain Thery committed
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
//		// get index
//		xmlChar* prop = xmlGetProp(x_node, BAD_CAST "id");
//		unsigned int id = atoi((char*)prop);
//		// get & set nbref
//		prop = xmlGetProp(x_node, BAD_CAST "refs");
//		unsigned int nbr = atoi((char*)prop);
//		setNbRefs(id, nbr);
//
//		if (nbr > 0)
//		{
////			for (MapNameId::iterator it = m_attribNameMap.begin(); it != m_attribNameMap.end(); ++it)
////			{
////				prop = xmlGetProp(x_node, BAD_CAST (it->first).c_str());
////				// if name of data unkwown then error
////				if (prop == NULL)
////				{
////					CGoGNerr << "inconsistent xml file"<<CGoGNendl;
////					return false;
////				}
////				m_tableAttribs[it->second]->input(id, std::string((char*)prop));
////			}
//		}
537
//	}
Sylvain Thery's avatar
Sylvain Thery committed
538
539
540
541
542
543
544
545
546
547
548
549
//	return true;
//}
//
//void AttributeContainer::saveXml(xmlTextWriterPtr writer, unsigned int id)
//{
//	if (m_nbAttributes == 0)
//		return;
//
//	// noeud du container
//	int rc = xmlTextWriterStartElement(writer, BAD_CAST "Attributes_Container");
//	rc = xmlTextWriterWriteFormatAttribute(writer,  BAD_CAST "id","%u",id);
//	rc = xmlTextWriterWriteFormatAttribute(writer,  BAD_CAST "BlockSize","%u",_BLOCKSIZE_);
550
//	rc = xmlTextWriterWriteFormatAttribute(writer,  BAD_CAST "size","%u",m_maxSize);
Sylvain Thery's avatar
Sylvain Thery committed
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
//
//	// recuperer le nombre d'attributs
//	unsigned int nbAtt = m_nbAttributes;
//	unsigned int sizeVectAtt = m_tableAttribs.size();
//
//	// noeud avec la liste de attributs
//	rc = xmlTextWriterStartElement(writer, BAD_CAST "Attributes_Names");
//	rc = xmlTextWriterWriteFormatAttribute(writer,  BAD_CAST "nb","%u",nbAtt);
//	rc = xmlTextWriterWriteFormatAttribute(writer,  BAD_CAST "sv","%u",sizeVectAtt);
//
//	// recuperer les attributs dans la map et les sauver
////	for (std::map<std::string, unsigned int>::iterator it = m_attribNameMap.begin(); it!= m_attribNameMap.end(); ++it)
////	{
////		int rc = xmlTextWriterStartElement(writer, BAD_CAST "Attribute");
////		rc = xmlTextWriterWriteAttribute(writer,  BAD_CAST "name",BAD_CAST (it->first).c_str());
////		const std::string& str_type = m_tableAttribs[it->second]->getTypeName();
////		rc = xmlTextWriterWriteAttribute(writer,  BAD_CAST "type",BAD_CAST str_type.c_str());
////		rc = xmlTextWriterWriteFormatAttribute(writer,  BAD_CAST "id","%u",it->second);
////		rc = xmlTextWriterEndElement(writer);
////	}
//	// fin du noeud
//	rc = xmlTextWriterEndElement(writer);
//
//	// parcourir le container et sauver les lignes
//	rc = xmlTextWriterStartElement(writer, BAD_CAST "Data_Lines");
////	rc = xmlTextWriterWriteFormatAttribute(writer,  BAD_CAST "size","%u",m_maxSize);
//	for (unsigned int i = 0; i != m_maxSize; ++i)
//	{
//		unsigned int nbr = getNbRefs(i);
//		rc = xmlTextWriterStartElement(writer, BAD_CAST "Line");
//		rc = xmlTextWriterWriteFormatAttribute(writer,  BAD_CAST "id","%u",i);
//		rc = xmlTextWriterWriteFormatAttribute(writer,  BAD_CAST "refs","%u",nbr);
//		if (nbr > 0)
//		{
//			// tous les attributs de la ligne
////			for (MapNameId::iterator it = m_attribNameMap.begin(); it!= m_attribNameMap.end(); ++it)
////			{
////				std::string st_att = m_tableAttribs[it->second]->output(i);
////				rc = xmlTextWriterWriteAttribute(writer,(xmlChar*)( (it->first).c_str()), (xmlChar*)( st_att.c_str()));
////			}
//		}
//		// fin du noeud Line
//		rc = xmlTextWriterEndElement(writer);
//	}
//	// fin du noeud Data Lines
//	rc = xmlTextWriterEndElement(writer);
//
//	// fin du noeud Container
//	rc = xmlTextWriterEndElement(writer);
//}
//
//unsigned int AttributeContainer::getIdXmlNode(xmlNodePtr node)
//{
//	xmlChar *prop = xmlGetProp(node, BAD_CAST "id");
Pierre Kraemer's avatar
Pierre Kraemer committed
605
//	unsigned int id = atoi((char*)prop);
Sylvain Thery's avatar
Sylvain Thery committed
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
//	return id;
//}
//
//bool AttributeContainer::loadXml(xmlNodePtr node)
//{
//	xmlChar *prop = xmlGetProp(node, BAD_CAST "BlockSize");
//	unsigned int bs = atoi((char*)prop);
//
//	if (bs != _BLOCKSIZE_)
//	{
//		CGoGNerr << "Chargement impossible, tailles de block differentes: "<<_BLOCKSIZE_<<" / " << bs << CGoGNendl;
//		return false;
//	}
//
////	prop = xmlGetProp(node, BAD_CAST "id");
////	unsigned int id = atoi((char*)prop);
//
//	prop = xmlGetProp(node, BAD_CAST "size");
//	m_maxSize = atoi((char*)prop);
//
//	char* ANnode = (char*)"Attributes_Names";
//	char* DLnode= (char*)"Data_Lines";
//
//	// calcul le nombre de block et les alloue
//	unsigned int nbb = m_maxSize/_BLOCKSIZE_;
//	if (m_maxSize%_BLOCKSIZE_)
//			nbb++;
//
//	m_holesBlocks.resize(nbb);
//	for (unsigned int i=0; i<nbb; ++i)
//		m_holesBlocks[i] = new HoleBlockRef;
//
//	//load Attributes
//	xmlNode* cur = node->children;
//	while ( strcmp((char*)(cur->name),ANnode))
//		cur = cur->next;
//	loadXmlAN(cur,nbb);
//
//	cur = node->children;
//	while ( strcmp((char*)(cur->name),DLnode))
//		cur = cur->next;
//	loadXmlDL(cur);
//
//	// recreate free holes in blocks
//	nbb--;
//	for (unsigned int i = 0; i < nbb; ++i)
//	{
//		if (m_holesBlocks[i]->updateHoles(_BLOCKSIZE_))
//			m_tableBlocksWithFree.push_back(i);
//	}
//	m_holesBlocks[nbb]->updateHoles(m_maxSize - nbb * _BLOCKSIZE_);
//
//	return true;
//}
Pierre Kraemer's avatar
Pierre Kraemer committed
660

Sylvain Thery's avatar
Sylvain Thery committed
661
void AttributeContainer::saveBin(CGoGNostream& fs, unsigned int id) const
Pierre Kraemer's avatar
Pierre Kraemer committed
662
{
Pierre Kraemer's avatar
Pierre Kraemer committed
663
	// en ascii id et taille les tailles
Pierre Kraemer's avatar
Pierre Kraemer committed
664
665

	std::vector<unsigned int> bufferui;
Sylvain Thery's avatar
Sylvain Thery committed
666
	bufferui.reserve(10);
Pierre Kraemer's avatar
Pierre Kraemer committed
667
668
669
670
671
672
673
674

	bufferui.push_back(id);
	bufferui.push_back(_BLOCKSIZE_);
	bufferui.push_back(m_holesBlocks.size());
	bufferui.push_back(m_tableBlocksWithFree.size());
	bufferui.push_back(m_nbAttributes);
	bufferui.push_back(m_size);
	bufferui.push_back(m_maxSize);
Sylvain Thery's avatar
Sylvain Thery committed
675
676
	bufferui.push_back(m_orbit);
	bufferui.push_back(m_nbUnknown);
Pierre Kraemer's avatar
Pierre Kraemer committed
677

Sylvain Thery's avatar
Sylvain Thery committed
678
	fs.write(reinterpret_cast<const char*>(&bufferui[0]), bufferui.size()*sizeof(unsigned int));
Pierre Kraemer's avatar
Pierre Kraemer committed
679

Pierre Kraemer's avatar
Pierre Kraemer committed
680
	unsigned int i = 0;
Sylvain Thery's avatar
Sylvain Thery committed
681

Sylvain Thery's avatar
Sylvain Thery committed
682
	for(std::vector<AttributeMultiVectorGen*>::const_iterator it = m_tableAttribs.begin(); it != m_tableAttribs.end(); ++it)
Pierre Kraemer's avatar
Pierre Kraemer committed
683
	{
684
		if (*it != NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
685
			(*it)->saveBin(fs, i++);
Sylvain Thery's avatar
Sylvain Thery committed
686
		else
Sylvain Thery's avatar
Sylvain Thery committed
687
		{
Sylvain Thery's avatar
Sylvain Thery committed
688
			CGoGNerr << "PB saving, NULL ptr in m_tableAttribs" <<  CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
689
690
			i++;
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
691
692
693
	}

	//en binaire les blocks de ref
Sylvain Thery's avatar
Sylvain Thery committed
694
	for (std::vector<HoleBlockRef*>::const_iterator it = m_holesBlocks.begin(); it != m_holesBlocks.end(); ++it)
Pierre Kraemer's avatar
Pierre Kraemer committed
695
		(*it)->saveBin(fs);
Pierre Kraemer's avatar
Pierre Kraemer committed
696
697

	// les indices des blocks libres
698
	fs.write(reinterpret_cast<const char*>(&m_tableBlocksWithFree[0]), m_tableBlocksWithFree.size() * sizeof(unsigned int));
Pierre Kraemer's avatar
Pierre Kraemer committed
699
700
}

701
unsigned int AttributeContainer::loadBinId(CGoGNistream& fs)
Pierre Kraemer's avatar
Pierre Kraemer committed
702
703
704
705
706
707
{
	unsigned int id;
	fs.read(reinterpret_cast<char*>(&id), sizeof(unsigned int));
	return id;
}

708
bool AttributeContainer::loadBin(CGoGNistream& fs)
Pierre Kraemer's avatar
Pierre Kraemer committed
709
{
710
	if (m_attributes_registry_map == NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
711
	{
712
		CGoGNerr << "Attribute Registry non initialized"<< CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
713
714
715
716
717
718
		return false;
	}

	std::vector<unsigned int> bufferui;
	bufferui.resize(256);

Sylvain Thery's avatar
Sylvain Thery committed
719
	fs.read(reinterpret_cast<char*>(&(bufferui[0])), 8*sizeof(unsigned int));	//WARNING 9 hard coded
Pierre Kraemer's avatar
Pierre Kraemer committed
720

Pierre Kraemer's avatar
Pierre Kraemer committed
721
	unsigned int bs, szHB, szBWF, nbAtt;
Pierre Kraemer's avatar
Pierre Kraemer committed
722
723
724
725
726
727
	bs = bufferui[0];
	szHB = bufferui[1];
	szBWF = bufferui[2];
	nbAtt = bufferui[3];
	m_size = bufferui[4];
	m_maxSize = bufferui[5];
Sylvain Thery's avatar
Sylvain Thery committed
728
729
730
	m_orbit = bufferui[6];
	m_nbUnknown = bufferui[7];

Pierre Kraemer's avatar
Pierre Kraemer committed
731
732
733

	if (bs != _BLOCKSIZE_)
	{
734
		CGoGNerr << "Loading unavailable, different block sizes: "<<_BLOCKSIZE_<<" / " << bs << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
735
736
737
		return false;
	}

Sylvain Thery's avatar
Sylvain Thery committed
738

739
	for (unsigned int j = 0; j < nbAtt; ++j)
Pierre Kraemer's avatar
Pierre Kraemer committed
740
741
742
	{
		std::string nameAtt;
		std::string typeAtt;
743
		/*unsigned int id = */AttributeMultiVectorGen::loadBinInfos(fs,nameAtt, typeAtt);
Pierre Kraemer's avatar
Pierre Kraemer committed
744
745
746
747

		std::map<std::string, RegisteredBaseAttribute*>::iterator itAtt = m_attributes_registry_map->find(typeAtt);
		if (itAtt == m_attributes_registry_map->end())
		{
748
			CGoGNout << "Skipping non registred attribute of type name"<< typeAtt <<CGoGNendl;
749
			AttributeMultiVectorGen::skipLoadBin(fs);
Pierre Kraemer's avatar
Pierre Kraemer committed
750
751
752
753
		}
		else
		{
			RegisteredBaseAttribute* ra = itAtt->second;
754
755
			AttributeMultiVectorGen* amvg = ra->addAttribute(*this, nameAtt);
			amvg->loadBin(fs);
Pierre Kraemer's avatar
Pierre Kraemer committed
756
757
758
759
760
761
		}
	}

	m_holesBlocks.resize(szHB);

	// blocks
Pierre Kraemer's avatar
Pierre Kraemer committed
762
	for (unsigned int i = 0; i < szHB; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
763
764
765
766
767
768
769
	{
		m_holesBlocks[i] = new HoleBlockRef;
		m_holesBlocks[i]->loadBin(fs);
	}

	// les indices des blocks libres
	m_tableBlocksWithFree.resize(szBWF);
770
	fs.read(reinterpret_cast<char*>(&(m_tableBlocksWithFree[0])), szBWF*sizeof(unsigned int));
Pierre Kraemer's avatar
Pierre Kraemer committed
771
772
773
774

	return true;
}

775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
void  AttributeContainer::copyFrom(const AttributeContainer& cont)
{
// 	clear is done from the map

	m_size = cont.m_size;
	m_maxSize = cont.m_maxSize;
	m_orbit = cont.m_orbit;
	m_nbUnknown = cont.m_nbUnknown;
	m_nbAttributes = cont.m_nbAttributes;
	m_lineCost = cont.m_lineCost;

	// blocks
	unsigned int sz = cont.m_holesBlocks.size();
	m_holesBlocks.resize(sz);
	for (unsigned int i = 0; i < sz; ++i)
		m_holesBlocks[i] = new HoleBlockRef(*(cont.m_holesBlocks[i]));

792
793
794
795
796
797
	//  free indices
	sz = cont.m_freeIndices.size();
	m_freeIndices.resize(sz);
	for (unsigned int i = 0; i < sz; ++i)
		m_freeIndices[i] = cont.m_freeIndices[i];

798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
	// blocks with free
	sz = cont.m_tableBlocksWithFree.size();
	m_tableBlocksWithFree.resize(sz);
	for (unsigned int i = 0; i < sz; ++i)
		m_tableBlocksWithFree[i] = cont.m_tableBlocksWithFree[i];

	// empty blocks
	sz = cont.m_tableBlocksEmpty.size();
	m_tableBlocksEmpty.resize(sz);
	for (unsigned int i = 0; i < sz; ++i)
		m_tableBlocksEmpty[i] = cont.m_tableBlocksEmpty[i];

	//attributes (warning attribute can have different numbers than in original)
	m_tableAttribs.reserve(m_nbAttributes);
	sz = cont.m_tableAttribs.size();
	for (unsigned int i = 0; i < sz; ++i)
	{
		if (cont.m_tableAttribs[i] != NULL)
		{
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
			std::string sub = cont.m_tableAttribs[i]->getName().substr(0, 5);
			if (sub != "Mark_") // Mark leaved by
			{
				AttributeMultiVectorGen* ptr = cont.m_tableAttribs[i]->new_obj();
				ptr->setName(cont.m_tableAttribs[i]->getName());
				ptr->setOrbit(cont.m_tableAttribs[i]->getOrbit());
				ptr->setIndex(m_tableAttribs.size());
				ptr->setNbBlocks(cont.m_tableAttribs[i]->getNbBlocks());
				ptr->copy(cont.m_tableAttribs[i]);
				m_tableAttribs.push_back(ptr);
			}
			else
			{
				// Mark always the first !
				AttributeMultiVectorGen* ptr = m_tableAttribs[i];
				ptr->setNbBlocks(cont.m_tableAttribs[i]->getNbBlocks());
				ptr->copy(cont.m_tableAttribs[i]);
			}
835
836
837
838
		}
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
839
}