MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 <utility> 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