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