1
5
6 #include "VarLenDenseTag.hpp"
7 #include "moab/Range.hpp"
8 #include "TagCompare.hpp"
9 #include "SysUtil.hpp"
10 #include "SequenceManager.hpp"
11 #include "SequenceData.hpp"
12 #include "RangeSeqIntersectIter.hpp"
13 #include "moab/Error.hpp"
14 #include "moab/ErrorHandler.hpp"
15 #include "moab/CN.hpp"
16 #include <utility>
17
18 namespace moab
19 {
20
21 inline static ErrorCode not_found( std::string , EntityHandle )
22 {
23 #if 0
24
25
26 if (h)
27 fprintf(stderr, "[Warning]: No variable-length dense tag %s value for %s %lu\n",
28 name.c_str(),
29 CN::EntityTypeName(TYPE_FROM_HANDLE(h)),
30 (unsigned long)ID_FROM_HANDLE(h));
31 else
32 fprintf(stderr, "[Warning]: No variable-length dense tag %s value for root set\n", name.c_str());
33 #endif
34
35 return MB_TAG_NOT_FOUND;
36 }
37
38 VarLenDenseTag::VarLenDenseTag( int index,
39 const char* name,
40 DataType type,
41 const void* default_value,
42 int default_value_size )
43 : TagInfo( name, MB_VARIABLE_LENGTH, type, default_value, default_value_size ), mySequenceArray( index )
44 {
45 }
46
47 VarLenDenseTag* VarLenDenseTag::create_tag( SequenceManager* seqman,
48 Error* error,
49 const char* name,
50 DataType type,
51 const void* default_value,
52 int default_value_size )
53 {
54 int index;
55 if( MB_SUCCESS != seqman->reserve_tag_array( error, MB_VARIABLE_LENGTH, index ) ) return NULL;
56
57 return new VarLenDenseTag( index, name, type, default_value, default_value_size );
58 }
59
60 VarLenDenseTag::~VarLenDenseTag()
61 {
62 assert( mySequenceArray < 0 );
63 }
64
65 TagType VarLenDenseTag::get_storage_type() const
66 {
67 return MB_TAG_DENSE;
68 }
69
70 ErrorCode VarLenDenseTag::release_all_data( SequenceManager* seqman, Error* error, bool delete_pending )
71 {
72 Range all_ents;
73 seqman->get_entities( all_ents );
74 ErrorCode rval = remove_data( seqman, error, all_ents );
75 if( MB_SUCCESS == rval )
76 {
77 rval = seqman->release_tag_array( error, mySequenceArray, delete_pending );
78 if( MB_SUCCESS == rval && delete_pending ) mySequenceArray = -1;
79 }
80
81 return rval;
82 }
83
84 ErrorCode VarLenDenseTag::get_array( const SequenceManager* seqman,
85 Error* ,
86 EntityHandle h,
87 const VarLenTag*& ptr,
88 size_t& count ) const
89 {
90 const EntitySequence* seq = NULL;
91 ErrorCode rval = seqman->find( h, seq );
92 if( MB_SUCCESS != rval )
93 {
94 if( !h )
95 {
96 ptr = &meshValue;
97 count = 1;
98 return MB_SUCCESS;
99 }
100 else
101 {
102 ptr = NULL;
103 count = 0;
104 return not_found( get_name(), h );
105 }
106 }
107
108 const void* mem = seq->data()->get_tag_data( mySequenceArray );
109 ptr = reinterpret_cast< const VarLenTag* >( mem );
110 count = seq->data()->end_handle() - h + 1;
111 if( ptr ) ptr += h - seq->data()->start_handle();
112
113 return MB_SUCCESS;
114 }
115
116 ErrorCode VarLenDenseTag::get_array( SequenceManager* seqman,
117 Error* ,
118 EntityHandle h,
119 VarLenTag*& ptr,
120 size_t& count,
121 bool allocate )
122 {
123 EntitySequence* seq = NULL;
124 ErrorCode rval = seqman->find( h, seq );
125 if( MB_SUCCESS != rval )
126 {
127 if( !h )
128 {
129 ptr = &meshValue;
130 count = 1;
131 return MB_SUCCESS;
132 }
133 else
134 {
135 ptr = NULL;
136 count = 0;
137 return not_found( get_name(), h );
138 }
139 }
140
141 void* mem = seq->data()->get_tag_data( mySequenceArray );
142 if( !mem && allocate )
143 {
144 mem = seq->data()->allocate_tag_array( mySequenceArray, sizeof( VarLenTag ) );
145 if( !mem )
146 {
147 MB_SET_ERR( MB_MEMORY_ALLOCATION_FAILED, "Memory allocation for variable-length dense tag data failed" );
148 }
149
150 memset( mem, 0, sizeof( VarLenTag ) * seq->data()->size() );
151 }
152
153 ptr = reinterpret_cast< VarLenTag* >( mem );
154 count = seq->data()->end_handle() - h + 1;
155 if( ptr ) ptr += h - seq->data()->start_handle();
156
157 return MB_SUCCESS;
158 }
159
160 ErrorCode VarLenDenseTag::get_data( const SequenceManager*,
161 Error* ,
162 const EntityHandle*,
163 size_t,
164 void* ) const
165 {
166 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
167 }
168
169 ErrorCode VarLenDenseTag::get_data( const SequenceManager*, Error* , const Range&, void* ) const
170 {
171 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
172 }
173
174 ErrorCode VarLenDenseTag::get_data( const SequenceManager* seqman,
175 Error* ,
176 const EntityHandle* entities,
177 size_t num_entities,
178 const void** pointers,
179 int* lengths ) const
180 {
181 if( !lengths )
182 {
183 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
184 }
185
186 ErrorCode result = MB_SUCCESS, rval;
187 const EntityHandle* const end = entities + num_entities;
188 size_t junk = 0;
189 const VarLenTag* ptr = NULL;
190
191 for( const EntityHandle* i = entities; i != end; ++i, ++pointers, ++lengths )
192 {
193 rval = get_array( seqman, NULL, *i, ptr, junk );MB_CHK_ERR( rval );
194
195 if( ptr && ptr->size() )
196 {
197 *pointers = ptr->data();
198 *lengths = ptr->size();
199 }
200 else if( get_default_value() )
201 {
202 *pointers = get_default_value();
203 *lengths = get_default_value_size();
204 }
205 else
206 {
207 *pointers = 0;
208 *lengths = 0;
209 result = not_found( get_name(), *i );
210 }
211 }
212
213 return result;
214 }
215
216 ErrorCode VarLenDenseTag::get_data( const SequenceManager* seqman,
217 Error* ,
218 const Range& entities,
219 const void** pointers,
220 int* lengths ) const
221 {
222 if( !lengths )
223 {
224 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
225 }
226
227 ErrorCode rval;
228 size_t avail = 0;
229 const VarLenTag* array = NULL;
230
231 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
232 {
233 EntityHandle start = p->first;
234 while( start <= p->second )
235 {
236 rval = get_array( seqman, NULL, start, array, avail );MB_CHK_ERR( rval );
237
238 const size_t count = std::min< size_t >( p->second - start + 1, avail );
239
240 if( !array )
241 {
242 const void* defval = get_default_value();
243 const int len = get_default_value_size();
244 SysUtil::setmem( pointers, &defval, sizeof( void* ), count );
245 SysUtil::setmem( lengths, &len, sizeof( int ), count );
246 pointers += count;
247 lengths += count;
248 if( !defval ) return not_found( get_name(), start );
249 }
250
251 const VarLenTag* end_data = array + count;
252 while( array != end_data )
253 {
254 if( array->size() )
255 {
256 *pointers = array->data();
257 *lengths = array->size();
258 }
259 else if( get_default_value() )
260 {
261 *pointers = get_default_value();
262 *lengths = get_default_value_size();
263 }
264 else
265 {
266 *pointers = NULL;
267 *lengths = 0;
268 return not_found( get_name(), start );
269 }
270 ++pointers;
271 ++lengths;
272 ++array;
273 ++start;
274 }
275 }
276 }
277
278 return MB_SUCCESS;
279 }
280
281 ErrorCode VarLenDenseTag::set_data( SequenceManager*, Error* , const EntityHandle*, size_t, const void* )
282 {
283 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
284 }
285
286 ErrorCode VarLenDenseTag::set_data( SequenceManager*, Error* , const Range&, const void* )
287 {
288 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
289 }
290
291 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman,
292 Error* ,
293 const EntityHandle* entities,
294 size_t num_entities,
295 bool one_value,
296 void const* const* pointers,
297 const int* lengths )
298 {
299 ErrorCode rval = validate_lengths( NULL, lengths, one_value ? 1 : num_entities );MB_CHK_ERR( rval );
300
301 const EntityHandle* const end = entities + num_entities;
302 VarLenTag* array = NULL;
303 size_t junk = 0;
304 const size_t step = one_value ? 0 : 1;
305
306 for( const EntityHandle* i = entities; i != end; ++i )
307 {
308 rval = get_array( seqman, NULL, *i, array, junk, true );MB_CHK_ERR( rval );
309
310 array->set( *pointers, *lengths );
311 pointers += step;
312 lengths += step;
313 }
314
315 return MB_SUCCESS;
316 }
317
318 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman,
319 Error* ,
320 const Range& entities,
321 bool one_value,
322 void const* const* pointers,
323 const int* lengths )
324 {
325 ErrorCode rval = validate_lengths( NULL, lengths, one_value ? 1 : entities.size() );MB_CHK_ERR( rval );
326
327 VarLenTag* array = NULL;
328 size_t avail = 0;
329 const size_t step = one_value ? 0 : 1;
330
331 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
332 {
333 EntityHandle start = p->first;
334 while( start <= p->second )
335 {
336 rval = get_array( seqman, NULL, start, array, avail, true );MB_CHK_ERR( rval );
337
338 const EntityHandle end = std::min< EntityHandle >( p->second + 1, start + avail );
339 while( start != end )
340 {
341 array->set( *pointers, *lengths );
342 ++start;
343 ++array;
344 pointers += step;
345 lengths += step;
346 }
347 }
348 }
349
350 return MB_SUCCESS;
351 }
352
353 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman,
354 Error* ,
355 const EntityHandle* entities,
356 size_t num_entities,
357 void const* const* pointers,
358 const int* lengths )
359 {
360 return set_data( seqman, NULL, entities, num_entities, false, pointers, lengths );
361 }
362
363 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman,
364 Error* ,
365 const Range& entities,
366 void const* const* pointers,
367 const int* lengths )
368 {
369 return set_data( seqman, NULL, entities, false, pointers, lengths );
370 }
371
372 ErrorCode VarLenDenseTag::clear_data( SequenceManager* seqman,
373 Error* ,
374 const EntityHandle* entities,
375 size_t num_entities,
376 const void* value_ptr,
377 int value_len )
378 {
379 if( !value_ptr || !value_len )
380 return remove_data( seqman, NULL, entities, num_entities );
381 else
382 return set_data( seqman, NULL, entities, num_entities, true, &value_ptr, &value_len );
383 }
384
385 ErrorCode VarLenDenseTag::clear_data( SequenceManager* seqman,
386 Error* ,
387 const Range& entities,
388 const void* value_ptr,
389 int value_len )
390 {
391 if( !value_ptr || !value_len )
392 return remove_data( seqman, NULL, entities );
393 else
394 return set_data( seqman, NULL, entities, true, &value_ptr, &value_len );
395 }
396
397 ErrorCode VarLenDenseTag::remove_data( SequenceManager* seqman,
398 Error* ,
399 const EntityHandle* entities,
400 size_t num_entities )
401 {
402 const EntityHandle* const end = entities + num_entities;
403 VarLenTag* array = NULL;
404 size_t junk = 0;
405 ErrorCode rval;
406
407 for( const EntityHandle* i = entities; i != end; ++i )
408 {
409 rval = get_array( seqman, NULL, *i, array, junk, false );MB_CHK_ERR( rval );
410
411 if( array ) array->clear();
412 }
413
414 return MB_SUCCESS;
415 }
416
417 ErrorCode VarLenDenseTag::remove_data( SequenceManager* seqman, Error* , const Range& entities )
418 {
419 VarLenTag* array = NULL;
420 size_t avail = 0;
421 ErrorCode rval;
422
423 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
424 {
425 EntityHandle start = p->first;
426 while( start <= p->second )
427 {
428 rval = get_array( seqman, NULL, start, array, avail, false );MB_CHK_ERR( rval );
429
430 const EntityHandle end = std::min< EntityHandle >( p->second + 1, start + avail );
431 if( array )
432 {
433 while( start != end )
434 {
435 array->clear();
436 ++start;
437 ++array;
438 }
439 }
440 else
441 {
442 start = end;
443 }
444 }
445 }
446
447 return MB_SUCCESS;
448 }
449
450 ErrorCode VarLenDenseTag::tag_iterate( SequenceManager*,
451 Error* ,
452 Range::iterator&,
453 const Range::iterator&,
454 void*&,
455 bool )
456 {
457 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "Cannot iterate over variable-length tag data" );
458 }
459
460 template < class Container >
461 static inline ErrorCode get_tagged( const SequenceManager* seqman,
462 int mySequenceArray,
463 EntityType type,
464 Container& entities )
465 {
466 typename Container::iterator hint = entities.begin();
467 std::pair< EntityType, EntityType > range = type_range( type );
468 TypeSequenceManager::const_iterator i;
469 const VarLenTag *data, *iter, *end;
470 for( EntityType t = range.first; t != range.second; ++t )
471 {
472 const TypeSequenceManager& map = seqman->entity_map( t );
473 for( i = map.begin(); i != map.end(); ++i )
474 {
475 data = reinterpret_cast< const VarLenTag* >( ( *i )->data()->get_tag_data( mySequenceArray ) );
476 if( !data ) continue;
477 end = data + ( *i )->end_handle() - ( *i )->data()->start_handle() + 1;
478 iter = data + ( *i )->start_handle() - ( *i )->data()->start_handle();
479 EntityHandle handle = ( *i )->start_handle();
480 for( ; iter != end; ++iter, ++handle )
481 if( iter->size() ) hint = entities.insert( hint, handle );
482 }
483 }
484
485 return MB_SUCCESS;
486 }
487
488 template < class Container >
489 static inline ErrorCode get_tagged( const SequenceManager* seqman,
490 int mySequenceArray,
491 Range::const_iterator begin,
492 Range::const_iterator end,
493 Container& entities )
494 {
495 typename Container::iterator hint = entities.begin();
496 RangeSeqIntersectIter iter( const_cast< SequenceManager* >( seqman ) );
497 ErrorCode rval = iter.init( begin, end );
498 const VarLenTag* data;
499 for( ; MB_SUCCESS == rval; rval = iter.step() )
500 {
501 data = reinterpret_cast< const VarLenTag* >( iter.get_sequence()->data()->get_tag_data( mySequenceArray ) );
502 if( !data ) continue;
503
504 data += iter.get_start_handle() - iter.get_sequence()->data()->start_handle();
505 size_t count = iter.get_end_handle() - iter.get_start_handle() + 1;
506 for( size_t i = 0; i < count; ++i )
507 if( data[i].size() ) hint = entities.insert( hint, iter.get_start_handle() + i );
508 rval = iter.step();
509 }
510
511 if( MB_FAILURE != rval )
512 return rval;
513
514 return MB_SUCCESS;
515 }
516
517 template < class Container >
518 static inline ErrorCode get_tagged( const SequenceManager* seqman,
519 int mySequenceArray,
520 Container& entities,
521 EntityType type,
522 const Range* intersect )
523 {
524 if( !intersect )
525 return get_tagged< Container >( seqman, mySequenceArray, type, entities );
526 else if( MBMAXTYPE == type )
527 return get_tagged< Container >( seqman, mySequenceArray, intersect->begin(), intersect->end(), entities );
528 else
529 {
530 std::pair< Range::iterator, Range::iterator > r = intersect->equal_range( type );
531 return get_tagged< Container >( seqman, mySequenceArray, r.first, r.second, entities );
532 }
533 }
534
535 ErrorCode VarLenDenseTag::get_tagged_entities( const SequenceManager* seqman,
536 Range& entities,
537 EntityType type,
538 const Range* intersect ) const
539 {
540 return get_tagged( seqman, mySequenceArray, entities, type, intersect );
541 }
542
543 ErrorCode VarLenDenseTag::num_tagged_entities( const SequenceManager* seqman,
544 size_t& output_count,
545 EntityType type,
546 const Range* intersect ) const
547 {
548 InsertCount counter( output_count );
549 ErrorCode rval = get_tagged( seqman, mySequenceArray, counter, type, intersect );
550 output_count = counter.end();
551 return rval;
552 }
553
554 ErrorCode VarLenDenseTag::find_entities_with_value( const SequenceManager* seqman,
555 Error* error,
556 Range& output_entities,
557 const void* value,
558 int value_bytes,
559 EntityType type,
560 const Range* intersect_entities ) const
561 {
562 if( !intersect_entities )
563 {
564 std::pair< EntityType, EntityType > range = type_range( type );
565 TypeSequenceManager::const_iterator i;
566 for( EntityType t = range.first; t != range.second; ++t )
567 {
568 const TypeSequenceManager& map = seqman->entity_map( t );
569 for( i = map.begin(); i != map.end(); ++i )
570 {
571 const void* data = ( *i )->data()->get_tag_data( mySequenceArray );
572 if( data )
573 {
574 ByteArrayIterator start( ( *i )->data()->start_handle(), data, *this );
575 ByteArrayIterator end( ( *i )->end_handle() + 1, 0, 0 );
576 start += ( *i )->start_handle() - ( *i )->data()->start_handle();
577 find_tag_varlen_values_equal( *this, value, value_bytes, start, end, output_entities );
578 }
579 }
580 }
581 }
582 else
583 {
584 const VarLenTag* array;
585 size_t count;
586 ErrorCode rval;
587
588 Range::const_pair_iterator p = intersect_entities->begin();
589 if( type != MBMAXTYPE )
590 {
591 p = intersect_entities->lower_bound( type );
592 assert( TYPE_FROM_HANDLE( p->first ) == type );
593 }
594 for( ;
595 p != intersect_entities->const_pair_end() && ( MBMAXTYPE == type || TYPE_FROM_HANDLE( p->first ) == type );
596 ++p )
597 {
598 EntityHandle start = p->first;
599 while( start <= p->second )
600 {
601 rval = get_array( seqman, error, start, array, count );MB_CHK_ERR( rval );
602
603 if( p->second - start < count - 1 ) count = p->second - start + 1;
604
605 if( array )
606 {
607 ByteArrayIterator istart( start, array, *this );
608 ByteArrayIterator iend( start + count, 0, 0 );
609 find_tag_varlen_values_equal( *this, value, value_bytes, istart, iend, output_entities );
610 }
611 start += count;
612 }
613 }
614 }
615
616 return MB_SUCCESS;
617 }
618
619 bool VarLenDenseTag::is_tagged( const SequenceManager* seqman, EntityHandle h ) const
620 {
621 const VarLenTag* ptr = NULL;
622 size_t count;
623 return ( MB_SUCCESS == get_array( seqman, 0, h, ptr, count ) ) && ( NULL != ptr ) && ( NULL != ptr->data() );
624 }
625
626 ErrorCode VarLenDenseTag::get_memory_use( const SequenceManager* seqman,
627 unsigned long& total,
628 unsigned long& per_entity ) const
629
630 {
631 total = 0;
632 per_entity = 0;
633 size_t count = 0;
634 for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
635 {
636 const TypeSequenceManager& map = seqman->entity_map( t );
637 const SequenceData* prev_data = 0;
638 for( TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i )
639 {
640 const void* mem = ( *i )->data()->get_tag_data( mySequenceArray );
641 if( !mem ) continue;
642
643 if( ( *i )->data() != prev_data )
644 {
645 total += ( *i )->data()->size();
646 prev_data = ( *i )->data();
647 }
648
649 count += ( *i )->size();
650 const VarLenTag* array = reinterpret_cast< const VarLenTag* >( mem );
651 for( int j = 0; j < ( *i )->size(); ++j )
652 per_entity += array[j].mem();
653 }
654 }
655 total *= sizeof( VarLenTag );
656 total += per_entity + sizeof( *this ) + TagInfo::get_memory_use();
657 total += meshValue.mem() + sizeof( meshValue );
658 if( count ) per_entity /= count;
659 per_entity += sizeof( VarLenTag );
660
661 return MB_SUCCESS;
662 }
663
664 }