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