![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /** \file VarLenDenseTag.cpp
00002 * \author Jason Kraftcheck
00003 * \date 2010-12-14
00004 */
00005
00006 #include "VarLenDenseTag.hpp"
00007 #include "moab/Range.hpp"
00008 #include "TagCompare.hpp"
00009 #include "SysUtil.hpp"
00010 #include "SequenceManager.hpp"
00011 #include "SequenceData.hpp"
00012 #include "RangeSeqIntersectIter.hpp"
00013 #include "moab/Error.hpp"
00014 #include "moab/ErrorHandler.hpp"
00015 #include "moab/CN.hpp"
00016 #include
00017
00018 namespace moab
00019 {
00020
00021 inline static ErrorCode not_found( std::string /*name*/, EntityHandle /*h*/ )
00022 {
00023 #if 0
00024 // MB_TAG_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
00025 // Print warning messages for debugging only
00026 if (h)
00027 fprintf(stderr, "[Warning]: No variable-length dense tag %s value for %s %lu\n",
00028 name.c_str(),
00029 CN::EntityTypeName(TYPE_FROM_HANDLE(h)),
00030 (unsigned long)ID_FROM_HANDLE(h));
00031 else
00032 fprintf(stderr, "[Warning]: No variable-length dense tag %s value for root set\n", name.c_str());
00033 #endif
00034
00035 return MB_TAG_NOT_FOUND;
00036 }
00037
00038 VarLenDenseTag::VarLenDenseTag( int index,
00039 const char* name,
00040 DataType type,
00041 const void* default_value,
00042 int default_value_size )
00043 : TagInfo( name, MB_VARIABLE_LENGTH, type, default_value, default_value_size ), mySequenceArray( index )
00044 {
00045 }
00046
00047 VarLenDenseTag* VarLenDenseTag::create_tag( SequenceManager* seqman,
00048 Error* error,
00049 const char* name,
00050 DataType type,
00051 const void* default_value,
00052 int default_value_size )
00053 {
00054 int index;
00055 if( MB_SUCCESS != seqman->reserve_tag_array( error, MB_VARIABLE_LENGTH, index ) ) return NULL;
00056
00057 return new VarLenDenseTag( index, name, type, default_value, default_value_size );
00058 }
00059
00060 VarLenDenseTag::~VarLenDenseTag()
00061 {
00062 assert( mySequenceArray < 0 );
00063 }
00064
00065 TagType VarLenDenseTag::get_storage_type() const
00066 {
00067 return MB_TAG_DENSE;
00068 }
00069
00070 ErrorCode VarLenDenseTag::release_all_data( SequenceManager* seqman, Error* error, bool delete_pending )
00071 {
00072 Range all_ents;
00073 seqman->get_entities( all_ents );
00074 ErrorCode rval = remove_data( seqman, error, all_ents );
00075 if( MB_SUCCESS == rval )
00076 {
00077 rval = seqman->release_tag_array( error, mySequenceArray, delete_pending );
00078 if( MB_SUCCESS == rval && delete_pending ) mySequenceArray = -1;
00079 }
00080
00081 return rval;
00082 }
00083
00084 ErrorCode VarLenDenseTag::get_array( const SequenceManager* seqman,
00085 Error* /* error */,
00086 EntityHandle h,
00087 const VarLenTag*& ptr,
00088 size_t& count ) const
00089 {
00090 const EntitySequence* seq = NULL;
00091 ErrorCode rval = seqman->find( h, seq );
00092 if( MB_SUCCESS != rval )
00093 {
00094 if( !h )
00095 { // Root set
00096 ptr = &meshValue;
00097 count = 1;
00098 return MB_SUCCESS;
00099 }
00100 else
00101 {
00102 ptr = NULL;
00103 count = 0;
00104 return not_found( get_name(), h );
00105 }
00106 }
00107
00108 const void* mem = seq->data()->get_tag_data( mySequenceArray );
00109 ptr = reinterpret_cast< const VarLenTag* >( mem );
00110 count = seq->data()->end_handle() - h + 1;
00111 if( ptr ) ptr += h - seq->data()->start_handle();
00112
00113 return MB_SUCCESS;
00114 }
00115
00116 ErrorCode VarLenDenseTag::get_array( SequenceManager* seqman,
00117 Error* /* error */,
00118 EntityHandle h,
00119 VarLenTag*& ptr,
00120 size_t& count,
00121 bool allocate )
00122 {
00123 EntitySequence* seq = NULL;
00124 ErrorCode rval = seqman->find( h, seq );
00125 if( MB_SUCCESS != rval )
00126 {
00127 if( !h )
00128 { // Root set
00129 ptr = &meshValue;
00130 count = 1;
00131 return MB_SUCCESS;
00132 }
00133 else
00134 {
00135 ptr = NULL;
00136 count = 0;
00137 return not_found( get_name(), h );
00138 }
00139 }
00140
00141 void* mem = seq->data()->get_tag_data( mySequenceArray );
00142 if( !mem && allocate )
00143 {
00144 mem = seq->data()->allocate_tag_array( mySequenceArray, sizeof( VarLenTag ) );
00145 if( !mem )
00146 {
00147 MB_SET_ERR( MB_MEMORY_ALLOCATION_FAILED, "Memory allocation for variable-length dense tag data failed" );
00148 }
00149
00150 memset( mem, 0, sizeof( VarLenTag ) * seq->data()->size() );
00151 }
00152
00153 ptr = reinterpret_cast< VarLenTag* >( mem );
00154 count = seq->data()->end_handle() - h + 1;
00155 if( ptr ) ptr += h - seq->data()->start_handle();
00156
00157 return MB_SUCCESS;
00158 }
00159
00160 ErrorCode VarLenDenseTag::get_data( const SequenceManager*,
00161 Error* /* error */,
00162 const EntityHandle*,
00163 size_t,
00164 void* ) const
00165 {
00166 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00167 }
00168
00169 ErrorCode VarLenDenseTag::get_data( const SequenceManager*, Error* /* error */, const Range&, void* ) const
00170 {
00171 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00172 }
00173
00174 ErrorCode VarLenDenseTag::get_data( const SequenceManager* seqman,
00175 Error* /* error */,
00176 const EntityHandle* entities,
00177 size_t num_entities,
00178 const void** pointers,
00179 int* lengths ) const
00180 {
00181 if( !lengths )
00182 {
00183 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00184 }
00185
00186 ErrorCode result = MB_SUCCESS, rval;
00187 const EntityHandle* const end = entities + num_entities;
00188 size_t junk = 0;
00189 const VarLenTag* ptr = NULL;
00190
00191 for( const EntityHandle* i = entities; i != end; ++i, ++pointers, ++lengths )
00192 {
00193 rval = get_array( seqman, NULL, *i, ptr, junk );MB_CHK_ERR( rval );
00194
00195 if( ptr && ptr->size() )
00196 {
00197 *pointers = ptr->data();
00198 *lengths = ptr->size();
00199 }
00200 else if( get_default_value() )
00201 {
00202 *pointers = get_default_value();
00203 *lengths = get_default_value_size();
00204 }
00205 else
00206 {
00207 *pointers = 0;
00208 *lengths = 0;
00209 result = not_found( get_name(), *i );
00210 }
00211 }
00212
00213 return result;
00214 }
00215
00216 ErrorCode VarLenDenseTag::get_data( const SequenceManager* seqman,
00217 Error* /* error */,
00218 const Range& entities,
00219 const void** pointers,
00220 int* lengths ) const
00221 {
00222 if( !lengths )
00223 {
00224 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00225 }
00226
00227 ErrorCode rval;
00228 size_t avail = 0;
00229 const VarLenTag* array = NULL;
00230
00231 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00232 {
00233 EntityHandle start = p->first;
00234 while( start <= p->second )
00235 {
00236 rval = get_array( seqman, NULL, start, array, avail );MB_CHK_ERR( rval );
00237
00238 const size_t count = std::min< size_t >( p->second - start + 1, avail );
00239
00240 if( !array )
00241 {
00242 const void* defval = get_default_value();
00243 const int len = get_default_value_size();
00244 SysUtil::setmem( pointers, &defval, sizeof( void* ), count );
00245 SysUtil::setmem( lengths, &len, sizeof( int ), count );
00246 pointers += count;
00247 lengths += count;
00248 if( !defval ) return not_found( get_name(), start );
00249 }
00250
00251 const VarLenTag* end_data = array + count;
00252 while( array != end_data )
00253 {
00254 if( array->size() )
00255 {
00256 *pointers = array->data();
00257 *lengths = array->size();
00258 }
00259 else if( get_default_value() )
00260 {
00261 *pointers = get_default_value();
00262 *lengths = get_default_value_size();
00263 }
00264 else
00265 {
00266 *pointers = NULL;
00267 *lengths = 0;
00268 return not_found( get_name(), start );
00269 }
00270 ++pointers;
00271 ++lengths;
00272 ++array;
00273 ++start;
00274 }
00275 }
00276 }
00277
00278 return MB_SUCCESS;
00279 }
00280
00281 ErrorCode VarLenDenseTag::set_data( SequenceManager*, Error* /* error */, const EntityHandle*, size_t, const void* )
00282 {
00283 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00284 }
00285
00286 ErrorCode VarLenDenseTag::set_data( SequenceManager*, Error* /* error */, const Range&, const void* )
00287 {
00288 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00289 }
00290
00291 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman,
00292 Error* /* error */,
00293 const EntityHandle* entities,
00294 size_t num_entities,
00295 bool one_value,
00296 void const* const* pointers,
00297 const int* lengths )
00298 {
00299 ErrorCode rval = validate_lengths( NULL, lengths, one_value ? 1 : num_entities );MB_CHK_ERR( rval );
00300
00301 const EntityHandle* const end = entities + num_entities;
00302 VarLenTag* array = NULL;
00303 size_t junk = 0;
00304 const size_t step = one_value ? 0 : 1;
00305
00306 for( const EntityHandle* i = entities; i != end; ++i )
00307 {
00308 rval = get_array( seqman, NULL, *i, array, junk, true );MB_CHK_ERR( rval );
00309
00310 array->set( *pointers, *lengths );
00311 pointers += step;
00312 lengths += step;
00313 }
00314
00315 return MB_SUCCESS;
00316 }
00317
00318 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman,
00319 Error* /* error */,
00320 const Range& entities,
00321 bool one_value,
00322 void const* const* pointers,
00323 const int* lengths )
00324 {
00325 ErrorCode rval = validate_lengths( NULL, lengths, one_value ? 1 : entities.size() );MB_CHK_ERR( rval );
00326
00327 VarLenTag* array = NULL;
00328 size_t avail = 0;
00329 const size_t step = one_value ? 0 : 1;
00330
00331 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00332 {
00333 EntityHandle start = p->first;
00334 while( start <= p->second )
00335 {
00336 rval = get_array( seqman, NULL, start, array, avail, true );MB_CHK_ERR( rval );
00337
00338 const EntityHandle end = std::min< EntityHandle >( p->second + 1, start + avail );
00339 while( start != end )
00340 {
00341 array->set( *pointers, *lengths );
00342 ++start;
00343 ++array;
00344 pointers += step;
00345 lengths += step;
00346 }
00347 }
00348 }
00349
00350 return MB_SUCCESS;
00351 }
00352
00353 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman,
00354 Error* /* error */,
00355 const EntityHandle* entities,
00356 size_t num_entities,
00357 void const* const* pointers,
00358 const int* lengths )
00359 {
00360 return set_data( seqman, NULL, entities, num_entities, false, pointers, lengths );
00361 }
00362
00363 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman,
00364 Error* /* error */,
00365 const Range& entities,
00366 void const* const* pointers,
00367 const int* lengths )
00368 {
00369 return set_data( seqman, NULL, entities, false, pointers, lengths );
00370 }
00371
00372 ErrorCode VarLenDenseTag::clear_data( SequenceManager* seqman,
00373 Error* /* error */,
00374 const EntityHandle* entities,
00375 size_t num_entities,
00376 const void* value_ptr,
00377 int value_len )
00378 {
00379 if( !value_ptr || !value_len )
00380 return remove_data( seqman, NULL, entities, num_entities );
00381 else
00382 return set_data( seqman, NULL, entities, num_entities, true, &value_ptr, &value_len );
00383 }
00384
00385 ErrorCode VarLenDenseTag::clear_data( SequenceManager* seqman,
00386 Error* /* error */,
00387 const Range& entities,
00388 const void* value_ptr,
00389 int value_len )
00390 {
00391 if( !value_ptr || !value_len )
00392 return remove_data( seqman, NULL, entities );
00393 else
00394 return set_data( seqman, NULL, entities, true, &value_ptr, &value_len );
00395 }
00396
00397 ErrorCode VarLenDenseTag::remove_data( SequenceManager* seqman,
00398 Error* /* error */,
00399 const EntityHandle* entities,
00400 size_t num_entities )
00401 {
00402 const EntityHandle* const end = entities + num_entities;
00403 VarLenTag* array = NULL;
00404 size_t junk = 0;
00405 ErrorCode rval;
00406
00407 for( const EntityHandle* i = entities; i != end; ++i )
00408 {
00409 rval = get_array( seqman, NULL, *i, array, junk, false );MB_CHK_ERR( rval );
00410
00411 if( array ) array->clear();
00412 }
00413
00414 return MB_SUCCESS;
00415 }
00416
00417 ErrorCode VarLenDenseTag::remove_data( SequenceManager* seqman, Error* /* error */, const Range& entities )
00418 {
00419 VarLenTag* array = NULL;
00420 size_t avail = 0;
00421 ErrorCode rval;
00422
00423 for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00424 {
00425 EntityHandle start = p->first;
00426 while( start <= p->second )
00427 {
00428 rval = get_array( seqman, NULL, start, array, avail, false );MB_CHK_ERR( rval );
00429
00430 const EntityHandle end = std::min< EntityHandle >( p->second + 1, start + avail );
00431 if( array )
00432 {
00433 while( start != end )
00434 {
00435 array->clear();
00436 ++start;
00437 ++array;
00438 }
00439 }
00440 else
00441 {
00442 start = end;
00443 }
00444 }
00445 }
00446
00447 return MB_SUCCESS;
00448 }
00449
00450 ErrorCode VarLenDenseTag::tag_iterate( SequenceManager*,
00451 Error* /* error */,
00452 Range::iterator&,
00453 const Range::iterator&,
00454 void*&,
00455 bool )
00456 {
00457 MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "Cannot iterate over variable-length tag data" );
00458 }
00459
00460 template < class Container >
00461 static inline ErrorCode get_tagged( const SequenceManager* seqman,
00462 int mySequenceArray,
00463 EntityType type,
00464 Container& entities )
00465 {
00466 typename Container::iterator hint = entities.begin();
00467 std::pair< EntityType, EntityType > range = type_range( type );
00468 TypeSequenceManager::const_iterator i;
00469 const VarLenTag *data, *iter, *end;
00470 for( EntityType t = range.first; t != range.second; ++t )
00471 {
00472 const TypeSequenceManager& map = seqman->entity_map( t );
00473 for( i = map.begin(); i != map.end(); ++i )
00474 {
00475 data = reinterpret_cast< const VarLenTag* >( ( *i )->data()->get_tag_data( mySequenceArray ) );
00476 if( !data ) continue;
00477 end = data + ( *i )->end_handle() - ( *i )->data()->start_handle() + 1;
00478 iter = data + ( *i )->start_handle() - ( *i )->data()->start_handle();
00479 EntityHandle handle = ( *i )->start_handle();
00480 for( ; iter != end; ++iter, ++handle )
00481 if( iter->size() ) hint = entities.insert( hint, handle );
00482 }
00483 }
00484
00485 return MB_SUCCESS;
00486 }
00487
00488 template < class Container >
00489 static inline ErrorCode get_tagged( const SequenceManager* seqman,
00490 int mySequenceArray,
00491 Range::const_iterator begin,
00492 Range::const_iterator end,
00493 Container& entities )
00494 {
00495 typename Container::iterator hint = entities.begin();
00496 RangeSeqIntersectIter iter( const_cast< SequenceManager* >( seqman ) );
00497 ErrorCode rval = iter.init( begin, end );
00498 const VarLenTag* data;
00499 for( ; MB_SUCCESS == rval; rval = iter.step() )
00500 {
00501 data = reinterpret_cast< const VarLenTag* >( iter.get_sequence()->data()->get_tag_data( mySequenceArray ) );
00502 if( !data ) continue;
00503
00504 data += iter.get_start_handle() - iter.get_sequence()->data()->start_handle();
00505 size_t count = iter.get_end_handle() - iter.get_start_handle() + 1;
00506 for( size_t i = 0; i < count; ++i )
00507 if( data[i].size() ) hint = entities.insert( hint, iter.get_start_handle() + i );
00508 rval = iter.step();
00509 }
00510
00511 if( MB_FAILURE != rval ) // We get MB_FAILURE at iterator end
00512 return rval;
00513
00514 return MB_SUCCESS;
00515 }
00516
00517 template < class Container >
00518 static inline ErrorCode get_tagged( const SequenceManager* seqman,
00519 int mySequenceArray,
00520 Container& entities,
00521 EntityType type,
00522 const Range* intersect )
00523 {
00524 if( !intersect )
00525 return get_tagged< Container >( seqman, mySequenceArray, type, entities );
00526 else if( MBMAXTYPE == type )
00527 return get_tagged< Container >( seqman, mySequenceArray, intersect->begin(), intersect->end(), entities );
00528 else
00529 {
00530 std::pair< Range::iterator, Range::iterator > r = intersect->equal_range( type );
00531 return get_tagged< Container >( seqman, mySequenceArray, r.first, r.second, entities );
00532 }
00533 }
00534
00535 ErrorCode VarLenDenseTag::get_tagged_entities( const SequenceManager* seqman,
00536 Range& entities,
00537 EntityType type,
00538 const Range* intersect ) const
00539 {
00540 return get_tagged( seqman, mySequenceArray, entities, type, intersect );
00541 }
00542
00543 ErrorCode VarLenDenseTag::num_tagged_entities( const SequenceManager* seqman,
00544 size_t& output_count,
00545 EntityType type,
00546 const Range* intersect ) const
00547 {
00548 InsertCount counter( output_count );
00549 ErrorCode rval = get_tagged( seqman, mySequenceArray, counter, type, intersect );
00550 output_count = counter.end();
00551 return rval;
00552 }
00553
00554 ErrorCode VarLenDenseTag::find_entities_with_value( const SequenceManager* seqman,
00555 Error* error,
00556 Range& output_entities,
00557 const void* value,
00558 int value_bytes,
00559 EntityType type,
00560 const Range* intersect_entities ) const
00561 {
00562 if( !intersect_entities )
00563 {
00564 std::pair< EntityType, EntityType > range = type_range( type );
00565 TypeSequenceManager::const_iterator i;
00566 for( EntityType t = range.first; t != range.second; ++t )
00567 {
00568 const TypeSequenceManager& map = seqman->entity_map( t );
00569 for( i = map.begin(); i != map.end(); ++i )
00570 {
00571 const void* data = ( *i )->data()->get_tag_data( mySequenceArray );
00572 if( data )
00573 {
00574 ByteArrayIterator start( ( *i )->data()->start_handle(), data, *this );
00575 ByteArrayIterator end( ( *i )->end_handle() + 1, 0, 0 );
00576 start += ( *i )->start_handle() - ( *i )->data()->start_handle();
00577 find_tag_varlen_values_equal( *this, value, value_bytes, start, end, output_entities );
00578 }
00579 }
00580 }
00581 }
00582 else
00583 {
00584 const VarLenTag* array;
00585 size_t count;
00586 ErrorCode rval;
00587
00588 Range::const_pair_iterator p = intersect_entities->begin();
00589 if( type != MBMAXTYPE )
00590 {
00591 p = intersect_entities->lower_bound( type );
00592 assert( TYPE_FROM_HANDLE( p->first ) == type );
00593 }
00594 for( ;
00595 p != intersect_entities->const_pair_end() && ( MBMAXTYPE == type || TYPE_FROM_HANDLE( p->first ) == type );
00596 ++p )
00597 {
00598 EntityHandle start = p->first;
00599 while( start <= p->second )
00600 {
00601 rval = get_array( seqman, error, start, array, count );MB_CHK_ERR( rval );
00602
00603 if( p->second - start < count - 1 ) count = p->second - start + 1;
00604
00605 if( array )
00606 {
00607 ByteArrayIterator istart( start, array, *this );
00608 ByteArrayIterator iend( start + count, 0, 0 );
00609 find_tag_varlen_values_equal( *this, value, value_bytes, istart, iend, output_entities );
00610 }
00611 start += count;
00612 }
00613 }
00614 }
00615
00616 return MB_SUCCESS;
00617 }
00618
00619 bool VarLenDenseTag::is_tagged( const SequenceManager* seqman, EntityHandle h ) const
00620 {
00621 const VarLenTag* ptr = NULL; // Initialize to get rid of warning
00622 size_t count;
00623 return ( MB_SUCCESS == get_array( seqman, 0, h, ptr, count ) ) && ( NULL != ptr ) && ( NULL != ptr->data() );
00624 }
00625
00626 ErrorCode VarLenDenseTag::get_memory_use( const SequenceManager* seqman,
00627 unsigned long& total,
00628 unsigned long& per_entity ) const
00629
00630 {
00631 total = 0;
00632 per_entity = 0;
00633 size_t count = 0;
00634 for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
00635 {
00636 const TypeSequenceManager& map = seqman->entity_map( t );
00637 const SequenceData* prev_data = 0;
00638 for( TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i )
00639 {
00640 const void* mem = ( *i )->data()->get_tag_data( mySequenceArray );
00641 if( !mem ) continue;
00642
00643 if( ( *i )->data() != prev_data )
00644 {
00645 total += ( *i )->data()->size();
00646 prev_data = ( *i )->data();
00647 }
00648
00649 count += ( *i )->size();
00650 const VarLenTag* array = reinterpret_cast< const VarLenTag* >( mem );
00651 for( int j = 0; j < ( *i )->size(); ++j )
00652 per_entity += array[j].mem();
00653 }
00654 }
00655 total *= sizeof( VarLenTag );
00656 total += per_entity + sizeof( *this ) + TagInfo::get_memory_use();
00657 total += meshValue.mem() + sizeof( meshValue );
00658 if( count ) per_entity /= count;
00659 per_entity += sizeof( VarLenTag );
00660
00661 return MB_SUCCESS;
00662 }
00663
00664 } // namespace moab