Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
VarLenDenseTag.cpp
Go to the documentation of this file.
1 /** \file VarLenDenseTag.cpp
2  * \author Jason Kraftcheck
3  * \date 2010-12-14
4  */
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"
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 /*name*/, EntityHandle /*h*/ )
22 {
23 #if 0
24  // MB_TAG_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
25  // Print warning messages for debugging only
26  if (h)
27  fprintf(stderr, "[Warning]: No variable-length dense tag %s value for %s %lu\n",
28  name.c_str(),
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 
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 
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 
61 {
62  assert( mySequenceArray < 0 );
63 }
64 
66 {
67  return MB_TAG_DENSE;
68 }
69 
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 
85  Error* /* 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  { // Root set
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 
117  Error* /* 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  { // Root set
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 
161  Error* /* 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* /* 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 
175  Error* /* 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 
217  Error* /* 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* /* 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* /* 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 
292  Error* /* 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 
319  Error* /* 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 
354  Error* /* 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 
364  Error* /* 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 
373  Error* /* 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 
386  Error* /* 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 
398  Error* /* 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 
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 
451  Error* /* error */,
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 );
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,
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 ) // We get MB_FAILURE at iterator end
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 
536  Range& entities,
537  EntityType type,
538  const Range* intersect ) const
539 {
540  return get_tagged( seqman, mySequenceArray, entities, type, intersect );
541 }
542 
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 
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 );
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 
620 {
621  const VarLenTag* ptr = NULL; // Initialize to get rid of warning
622  size_t count;
623  return ( MB_SUCCESS == get_array( seqman, 0, h, ptr, count ) ) && ( NULL != ptr ) && ( NULL != ptr->data() );
624 }
625 
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 } // namespace moab