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