moab
|
00001 00017 /********************************************** 00018 * Filename : SparseTagSuperCollection.cpp 00019 * 00020 * Purpose : To store any size data with 00021 * any entity handle 00022 * 00023 * Creator : Clinton Stimpson 00024 * 00025 * Date : 3 April 2002 00026 * 00027 * ********************************************/ 00028 00029 00030 #include <memory.h> 00031 #include <algorithm> 00032 00033 #include "SparseTagSuperCollection.hpp" 00034 #include "SparseTagCollection.hpp" 00035 #include "moab/Range.hpp" 00036 00037 namespace moab { 00038 00039 /* 00040 SparseTagSuperCollection functions ----------------------------- 00041 */ 00042 00043 SparseTagSuperCollection::~SparseTagSuperCollection() 00044 { 00045 std::vector<SparseTagCollection*>::iterator tag_iterator; 00046 for(tag_iterator = mDataTags.begin(); tag_iterator != mDataTags.end(); ++tag_iterator) 00047 delete *tag_iterator; 00048 mDataTags.clear(); 00049 } 00050 00051 void SparseTagSuperCollection::reset_data() 00052 { 00053 std::vector<SparseTagCollection*>::iterator tag_iterator; 00054 for(tag_iterator = mDataTags.begin(); tag_iterator != mDataTags.end(); ++tag_iterator) 00055 { 00056 if (*tag_iterator) { 00057 int data_size = (*tag_iterator)->tag_size(); 00058 delete *tag_iterator; 00059 *tag_iterator = new SparseTagCollection(data_size); 00060 } 00061 } 00062 00063 } 00064 00065 ErrorCode SparseTagSuperCollection::reserve_tag_id(int data_size, TagId tag_id) 00066 { 00067 if(data_size<=0 && data_size != MB_VARIABLE_LENGTH) 00068 return MB_FAILURE; 00069 00070 if (tag_id >= mDataTags.size()) 00071 mDataTags.resize( tag_id+1, 0 ); 00072 00073 if (mDataTags[tag_id]) 00074 return MB_FAILURE; 00075 00076 mDataTags[tag_id] = new SparseTagCollection(data_size); 00077 return MB_SUCCESS; 00078 } 00079 00080 ErrorCode SparseTagSuperCollection::release_tag_id(TagId tag_id) 00081 { 00082 if (tag_id >= mDataTags.size() || !mDataTags[tag_id]) 00083 return MB_TAG_NOT_FOUND; 00084 00085 delete mDataTags[tag_id]; 00086 mDataTags[tag_id] = 0; 00087 return MB_SUCCESS; 00088 } 00089 00090 int SparseTagSuperCollection::tag_size(const TagId tag_id) const 00091 { 00092 SparseTagCollection* coll = get_collection(tag_id); 00093 return coll ? coll->tag_size() : 0; 00094 } 00095 00096 00097 ErrorCode SparseTagSuperCollection::set_data( TagId tag_handle, 00098 const EntityHandle* handles, 00099 int num_handles, 00100 const void* data ) 00101 { 00102 SparseTagCollection* coll = get_collection(tag_handle); 00103 if (!coll) 00104 return MB_TAG_NOT_FOUND; 00105 00106 const int length = coll->tag_size(); 00107 if (length == MB_VARIABLE_LENGTH) 00108 return MB_VARIABLE_DATA_LENGTH; 00109 00110 ErrorCode rval, result = MB_SUCCESS; 00111 const unsigned char* ptr = reinterpret_cast<const unsigned char*>(data); 00112 const EntityHandle *const end = handles + num_handles; 00113 for (const EntityHandle* i = handles; i != end; ++i, ptr += length) { 00114 rval = coll->set_data( *i, ptr ); 00115 if (MB_SUCCESS != rval) 00116 result = rval; 00117 } 00118 00119 return result; 00120 } 00121 00122 ErrorCode SparseTagSuperCollection::set_data( TagId tag_handle, 00123 const EntityHandle* handles, 00124 int num_handles, 00125 void const* const* data_ptrs, 00126 const int* lengths, 00127 bool one_value ) 00128 { 00129 SparseTagCollection* coll = get_collection(tag_handle); 00130 if (!coll) 00131 return MB_TAG_NOT_FOUND; 00132 00133 const bool step = !one_value; 00134 const int length = coll->tag_size(); 00135 int length_step; 00136 if (length == MB_VARIABLE_LENGTH) { 00137 if (!lengths) 00138 return MB_VARIABLE_DATA_LENGTH; 00139 length_step = step; 00140 } 00141 else { 00142 lengths = &length; 00143 length_step = 0; 00144 } 00145 00146 ErrorCode rval, result = MB_SUCCESS; 00147 const EntityHandle *const end = handles + num_handles; 00148 void const* const* ptr = data_ptrs; 00149 for (const EntityHandle* i = handles; i != end; ++i, ptr += step, lengths += length_step) { 00150 rval = coll->set_data( *i, *ptr, *lengths ); 00151 if (MB_SUCCESS != rval) 00152 result = rval; 00153 } 00154 00155 return result; 00156 } 00157 00158 00159 ErrorCode SparseTagSuperCollection::set_data( TagId tag_handle, 00160 const Range& handles, 00161 const void* data ) 00162 { 00163 SparseTagCollection* coll = get_collection(tag_handle); 00164 if (!coll) 00165 return MB_TAG_NOT_FOUND; 00166 00167 const int length = coll->tag_size(); 00168 if (length == MB_VARIABLE_LENGTH) 00169 return MB_VARIABLE_DATA_LENGTH; 00170 00171 ErrorCode rval, result = MB_SUCCESS; 00172 const unsigned char* ptr = reinterpret_cast<const unsigned char*>(data); 00173 for (Range::const_iterator i = handles.begin(); i != handles.end(); ++i, ptr += length) { 00174 rval = coll->set_data( *i, ptr ); 00175 if (MB_SUCCESS != rval) 00176 result = rval; 00177 } 00178 00179 return result; 00180 } 00181 00182 ErrorCode SparseTagSuperCollection::set_data( TagId tag_handle, 00183 const Range& handles, 00184 void const* const* data_ptrs, 00185 const int* lengths, 00186 bool one_value ) 00187 { 00188 SparseTagCollection* coll = get_collection(tag_handle); 00189 if (!coll) 00190 return MB_TAG_NOT_FOUND; 00191 00192 const bool step = !one_value; 00193 const int length = coll->tag_size(); 00194 int length_step; 00195 if (length == MB_VARIABLE_LENGTH) { 00196 if (!lengths) 00197 return MB_VARIABLE_DATA_LENGTH; 00198 length_step = step; 00199 } 00200 else { 00201 lengths = &length; 00202 length_step = 0; 00203 } 00204 00205 ErrorCode rval, result = MB_SUCCESS; 00206 void const* const* ptr = data_ptrs; 00207 for (Range::const_iterator i = handles.begin(); i != handles.end(); ++i, ptr += step, lengths += length_step) { 00208 rval = coll->set_data( *i, *ptr, *lengths ); 00209 if (MB_SUCCESS != rval) 00210 result = rval; 00211 } 00212 00213 return result; 00214 } 00215 00216 ErrorCode SparseTagSuperCollection::tag_iterate( TagId tag_handle, 00217 Range::iterator& iter, 00218 const Range::iterator& end, 00219 void*& data_ptr_out, 00220 const void* default_value ) 00221 00222 { 00223 // Note: We are asked to returning a block of contiguous storage 00224 // for some block of contiguous handles for which the tag 00225 // storage is also contiguous. As sparse tag storage is 00226 // never contigous, all we can do is return a pointer to the 00227 // data for the first entity. 00228 00229 // If asked for nothing, successfully return nothing. 00230 if (iter == end) 00231 return MB_SUCCESS; 00232 00233 SparseTagCollection* coll = get_collection(tag_handle); 00234 if (!coll) 00235 return MB_TAG_NOT_FOUND; 00236 00237 // not supported for variable-length tags 00238 const int length = coll->tag_size(); 00239 if (length == MB_VARIABLE_LENGTH) 00240 return MB_VARIABLE_DATA_LENGTH; 00241 00242 // get pointer to tag storage for entity pointed to by iter 00243 int junk; 00244 ErrorCode rval = coll->get_data( *iter, data_ptr_out, junk ); 00245 if (MB_SUCCESS != rval) { 00246 // if no tag value but default_value, then set tag to 00247 // default_value and return the new tag storage. Note: 00248 // it is not sufficient to return the passed default_value 00249 // pointer because we are returning an non-const pointer that 00250 // could be modified by the caller. 00251 if (MB_TAG_NOT_FOUND == rval && default_value) { 00252 rval = coll->set_data( *iter, default_value ); 00253 if (MB_SUCCESS != rval) 00254 return rval; 00255 rval = coll->get_data( *iter, data_ptr_out, junk ); 00256 if (MB_SUCCESS != rval) 00257 return rval; 00258 } 00259 else { 00260 return rval; 00261 } 00262 } 00263 00264 // increment iterator and return 00265 ++iter; 00266 return MB_SUCCESS; 00267 } 00268 00269 ErrorCode SparseTagSuperCollection::get_data( TagId tag_handle, 00270 const EntityHandle* handles, 00271 int num_handles, 00272 void* data, 00273 const void* default_value ) const 00274 { 00275 SparseTagCollection* coll = get_collection(tag_handle); 00276 if (!coll) 00277 return MB_TAG_NOT_FOUND; 00278 00279 const int length = coll->tag_size(); 00280 if (length == MB_VARIABLE_LENGTH) 00281 return MB_VARIABLE_DATA_LENGTH; 00282 00283 ErrorCode rval; 00284 unsigned char* ptr = reinterpret_cast<unsigned char*>(data); 00285 const EntityHandle *const end = handles + num_handles; 00286 for (const EntityHandle* i = handles; i != end; ++i, ptr += length) { 00287 rval = coll->get_data( *i, ptr ); 00288 if (MB_SUCCESS != rval) { 00289 if (MB_TAG_NOT_FOUND == rval && default_value) 00290 memcpy( ptr, default_value, length ); 00291 else 00292 return rval; 00293 } 00294 } 00295 00296 return MB_SUCCESS; 00297 } 00298 00299 ErrorCode SparseTagSuperCollection::get_data( TagId tag_handle, 00300 const EntityHandle* handles, 00301 int num_handles, 00302 const void** data, 00303 int* lengths, 00304 const void* default_value, 00305 int default_val_length ) const 00306 { 00307 SparseTagCollection* coll = get_collection(tag_handle); 00308 if (!coll) 00309 return MB_TAG_NOT_FOUND; 00310 00311 int junk_length; 00312 int length_step = 1; 00313 const int length = coll->tag_size(); 00314 if (!lengths) { 00315 if (length == MB_VARIABLE_LENGTH) 00316 return MB_VARIABLE_DATA_LENGTH; 00317 lengths = &junk_length; 00318 length_step = 0; 00319 } 00320 00321 00322 ErrorCode rval, result = MB_SUCCESS; 00323 const EntityHandle *const end = handles + num_handles; 00324 for (const EntityHandle* i = handles; i != end; ++i, ++data, lengths += length_step) { 00325 void* ptr; 00326 rval = coll->get_data( *i, ptr, *lengths ); 00327 if (MB_SUCCESS == rval) 00328 *data = ptr; 00329 else if (MB_TAG_NOT_FOUND == rval && default_value) { 00330 *data = default_value; 00331 *lengths = default_val_length; 00332 } 00333 else { 00334 *data = 0; 00335 *lengths = 0; 00336 result = rval; 00337 } 00338 } 00339 00340 return result; 00341 } 00342 00343 00344 ErrorCode SparseTagSuperCollection::get_data( TagId tag_handle, 00345 const Range& handles, 00346 void* data, 00347 const void* default_value ) const 00348 { 00349 SparseTagCollection* coll = get_collection(tag_handle); 00350 if (!coll) 00351 return MB_TAG_NOT_FOUND; 00352 00353 const int length = coll->tag_size(); 00354 if (length == MB_VARIABLE_LENGTH) 00355 return MB_VARIABLE_DATA_LENGTH; 00356 00357 ErrorCode rval; 00358 unsigned char* ptr = reinterpret_cast<unsigned char*>(data); 00359 for (Range::const_iterator i = handles.begin(); i != handles.end(); ++i, ptr += length) { 00360 rval = coll->get_data( *i, ptr ); 00361 if (MB_SUCCESS != rval) { 00362 if (MB_TAG_NOT_FOUND == rval && default_value) 00363 memcpy( ptr, default_value, length ); 00364 else 00365 return rval; 00366 } 00367 } 00368 00369 return MB_SUCCESS; 00370 } 00371 00372 ErrorCode SparseTagSuperCollection::get_data( TagId tag_handle, 00373 const Range& handles, 00374 const void** data, 00375 int* lengths, 00376 const void* default_value, 00377 int default_val_length ) const 00378 { 00379 SparseTagCollection* coll = get_collection(tag_handle); 00380 if (!coll) 00381 return MB_TAG_NOT_FOUND; 00382 00383 int junk_length; 00384 int length_step = 1; 00385 const int length = coll->tag_size(); 00386 if (!lengths) { 00387 if (length == MB_VARIABLE_LENGTH) 00388 return MB_VARIABLE_DATA_LENGTH; 00389 lengths = &junk_length; 00390 length_step = 0; 00391 } 00392 00393 00394 ErrorCode rval, result = MB_SUCCESS; 00395 for (Range::const_iterator i = handles.begin(); i != handles.end(); ++i, ++data, lengths += length_step) { 00396 void* ptr; 00397 rval = coll->get_data( *i, ptr, *lengths ); 00398 if (MB_SUCCESS == rval) { 00399 *data = ptr; 00400 } 00401 else if (MB_TAG_NOT_FOUND == rval && default_value) { 00402 *data = default_value; 00403 *lengths = default_val_length; 00404 } 00405 else { 00406 *data = 0; 00407 *lengths = 0; 00408 result = rval; 00409 } 00410 } 00411 00412 return result; 00413 } 00414 00415 ErrorCode SparseTagSuperCollection::remove_data( const TagId tag_handle, 00416 const EntityHandle entity_handle ) 00417 { 00418 SparseTagCollection* coll = get_collection(tag_handle); 00419 return coll ? coll->remove_data( entity_handle ) : MB_TAG_NOT_FOUND; 00420 } 00421 00422 00424 ErrorCode SparseTagSuperCollection::get_entities(const TagId tag_handle, 00425 Range &entities) 00426 { 00427 SparseTagCollection* coll = get_collection(tag_handle); 00428 return coll ? coll->get_entities(entities) : MB_TAG_NOT_FOUND; 00429 } 00430 00432 ErrorCode SparseTagSuperCollection::get_entities(const TagId tag_handle, const EntityType type, 00433 Range &entities) 00434 { 00435 SparseTagCollection* coll = get_collection(tag_handle); 00436 return coll ? coll->get_entities(type, entities) : MB_TAG_NOT_FOUND; 00437 } 00438 00440 ErrorCode SparseTagSuperCollection::get_entities(const Range &range, 00441 const TagId tag_handle, const EntityType type, 00442 Range &entities) 00443 { 00444 SparseTagCollection* coll = get_collection(tag_handle); 00445 if (!coll) 00446 return MB_TAG_NOT_FOUND; 00447 00448 Range dum_range; 00449 ErrorCode result = coll->get_entities(type, dum_range); 00450 00451 std::set_intersection(dum_range.begin(), dum_range.end(), 00452 range.begin(), range.end(), 00453 range_inserter(entities)); 00454 00455 return result; 00456 } 00457 00458 ErrorCode SparseTagSuperCollection::get_tags(const EntityHandle entity, 00459 std::vector<Tag> &all_tags) 00460 { 00461 for (TagId id = 0; id < mDataTags.size(); ++id) 00462 if (mDataTags[id] && mDataTags[id]->contains(entity)) 00463 all_tags.push_back( TAG_HANDLE_FROM_ID( id, MB_TAG_SPARSE ) ); 00464 00465 return MB_SUCCESS; 00466 } 00467 00469 ErrorCode SparseTagSuperCollection::get_entities_with_tag_value( 00470 const TagId tag_handle, 00471 const TagInfo& tag_info, 00472 const EntityType type, 00473 Range &entities, 00474 const void* tag_value, 00475 int value_size) 00476 { 00477 SparseTagCollection* coll = get_collection(tag_handle); 00478 if (!coll) 00479 return MB_TAG_NOT_FOUND; 00480 00481 return coll->get_entities_with_tag_value(tag_info, type, entities, tag_value, value_size); 00482 } 00483 00485 ErrorCode SparseTagSuperCollection::get_entities_with_tag_value( 00486 const Range &range, 00487 const TagId tag_handle, 00488 const TagInfo& tag_info, 00489 const EntityType type, 00490 Range &entities, 00491 const void* tag_value, 00492 int value_size) 00493 { 00494 SparseTagCollection* coll = get_collection(tag_handle); 00495 if (!coll) 00496 return MB_TAG_NOT_FOUND; 00497 00498 Range dum_range; 00499 ErrorCode result = coll->get_entities_with_tag_value( 00500 tag_info, type, dum_range, tag_value, value_size); 00501 00502 // do this the hard way to preserve order in the vector 00503 std::set_intersection(range.begin(), range.end(), 00504 dum_range.begin(), dum_range.end(), 00505 range_inserter(entities)); 00506 00507 return result; 00508 } 00509 00511 ErrorCode SparseTagSuperCollection::get_number_entities(const TagId tag_handle, const EntityType type, 00512 int& num_entities) 00513 { 00514 SparseTagCollection* coll = get_collection(tag_handle); 00515 return coll ? coll->get_number_entities( type, num_entities ) : MB_TAG_NOT_FOUND; 00516 } 00517 00519 ErrorCode SparseTagSuperCollection::get_number_entities(const Range &range, 00520 const TagId tag_handle, const EntityType type, 00521 int& num_entities) 00522 { 00523 Range dum_range; 00524 ErrorCode result = get_entities(range, tag_handle, type, dum_range); 00525 num_entities = dum_range.size(); 00526 return result; 00527 } 00528 00529 00530 ErrorCode SparseTagSuperCollection::get_memory_use( TagId tag_id, 00531 unsigned long& total, 00532 unsigned long& per_entity ) 00533 { 00534 SparseTagCollection* coll = get_collection(tag_id); 00535 if (!coll) 00536 return MB_TAG_NOT_FOUND; 00537 00538 // 3*sizeof(void*) - std::map RB tree node 00539 // sizeof(void*)*sizeof(EntityHandle) - data in std::map node 00540 // coll->tag_size() - the actual tag data 00541 per_entity = 4*sizeof(void*)+sizeof(EntityHandle)+coll->tag_size(); 00542 00543 // Count number of occupied slots in mDataTags vector 00544 unsigned num_coll =0; 00545 for (unsigned i = 0; i < mDataTags.size(); ++i) 00546 if (mDataTags[i]) 00547 ++num_coll; 00548 00549 // amortized space in mDataTags vector 00550 total = sizeof(SparseTagCollection*) * mDataTags.capacity() / num_coll; 00551 // SparseTagCollection object for this tag 00552 total += sizeof(SparseTagCollection); 00553 // Per-entity data in SparseTagCollection 00554 total += per_entity * coll->get_number_entities(); 00555 return MB_SUCCESS; 00556 } 00557 00558 } // namespace moab 00559 00560 00561 00562