Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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" 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 /*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(), 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* /* 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  116 ErrorCode VarLenDenseTag::get_array( SequenceManager* seqman, 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  160 ErrorCode VarLenDenseTag::get_data( const SequenceManager*, 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  174 ErrorCode VarLenDenseTag::get_data( const SequenceManager* seqman, 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  216 ErrorCode VarLenDenseTag::get_data( const SequenceManager* seqman, 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  291 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman, 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  318 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman, 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  353 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman, 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  363 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman, 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  372 ErrorCode VarLenDenseTag::clear_data( SequenceManager* seqman, 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  385 ErrorCode VarLenDenseTag::clear_data( SequenceManager* seqman, 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  397 ErrorCode VarLenDenseTag::remove_data( SequenceManager* seqman, 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  417 ErrorCode VarLenDenseTag::remove_data( SequenceManager* seqman, Error* /* 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* /* 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 ) // 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  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; // 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  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 } // namespace moab