moab
|
00001 00016 #include <memory.h> 00017 #include <algorithm> 00018 00019 #include "VarLenSparseTag.hpp" 00020 #include "moab/Range.hpp" 00021 #include "TagCompare.hpp" 00022 #include "SequenceManager.hpp" 00023 #include "moab/Error.hpp" 00024 #include "moab/CN.hpp" 00025 00026 namespace moab { 00027 00028 static ErrorCode not_found( Error* error, std::string name, EntityHandle h ) 00029 { 00030 if (error) { 00031 if (h) 00032 error->set_last_error( "No tag %s value for %s %lu", 00033 name.c_str(), 00034 CN::EntityTypeName(TYPE_FROM_HANDLE(h)), 00035 (unsigned long)ID_FROM_HANDLE(h)); 00036 else 00037 error->set_last_error( "No tag %s value for root set", name.c_str()); 00038 } 00039 return MB_TAG_NOT_FOUND; 00040 } 00041 00042 static ErrorCode not_var_len( Error* error, std::string name ) 00043 { 00044 error->set_last_error( "No size specified for variable-length tag %s data", name.c_str()); 00045 return MB_VARIABLE_DATA_LENGTH; 00046 } 00047 00048 VarLenSparseTag::VarLenSparseTag( const char* name, 00049 DataType type, 00050 const void* default_value, 00051 int default_value_bytes ) 00052 : TagInfo( name, MB_VARIABLE_LENGTH, type, default_value, default_value_bytes ) 00053 { } 00054 00055 VarLenSparseTag::~VarLenSparseTag() 00056 { release_all_data(0,0,true); } 00057 00058 TagType VarLenSparseTag::get_storage_type() const 00059 { return MB_TAG_SPARSE; } 00060 00061 ErrorCode VarLenSparseTag::release_all_data( SequenceManager*, Error*, bool ) 00062 { 00063 mData.clear(); 00064 return MB_SUCCESS; 00065 } 00066 00067 ErrorCode VarLenSparseTag::get_data_ptr( Error* error, 00068 EntityHandle entity_handle, 00069 const void*& ptr, 00070 int& length ) const 00071 { 00072 MapType::const_iterator iter = mData.find(entity_handle); 00073 00074 if (iter != mData.end()) { 00075 ptr = iter->second.data(); 00076 length = iter->second.size(); 00077 } 00078 else if (get_default_value()) { 00079 ptr = get_default_value(); 00080 length = get_default_value_size(); 00081 } 00082 else 00083 return not_found(error, get_name(), entity_handle); 00084 00085 return MB_SUCCESS; 00086 } 00087 00088 ErrorCode VarLenSparseTag::get_data( const SequenceManager*, 00089 Error* error, 00090 const EntityHandle* , 00091 size_t , 00092 void* ) const 00093 { 00094 return not_var_len(error, get_name()); 00095 } 00096 00097 ErrorCode VarLenSparseTag::get_data( const SequenceManager*, 00098 Error* error, 00099 const Range& /*entities*/, 00100 void* /*data */) const 00101 { 00102 return not_var_len(error, get_name()); 00103 } 00104 00105 ErrorCode VarLenSparseTag::get_data( const SequenceManager* , 00106 Error* error, 00107 const EntityHandle* entities, 00108 size_t num_entities, 00109 const void** pointers, 00110 int* lengths ) const 00111 { 00112 if (!lengths) 00113 return not_var_len(error, get_name()); 00114 00115 ErrorCode rval; 00116 for (size_t i = 0; i < num_entities; ++i) 00117 if (MB_SUCCESS != (rval = get_data_ptr(error, entities[i], pointers[i], lengths[i]))) 00118 return rval; 00119 return MB_SUCCESS; 00120 } 00121 00122 ErrorCode VarLenSparseTag::get_data( const SequenceManager*, 00123 Error* error, 00124 const Range& entities, 00125 const void** pointers, 00126 int* lengths ) const 00127 { 00128 if (!lengths) 00129 return not_var_len(error, get_name()); 00130 00131 ErrorCode rval; 00132 Range::const_iterator i; 00133 for (i = entities.begin(); i != entities.end(); ++i, ++pointers, ++lengths) 00134 if (MB_SUCCESS != (rval = get_data_ptr(error, *i, *pointers, *lengths))) 00135 return rval; 00136 return MB_SUCCESS; 00137 } 00138 00139 ErrorCode VarLenSparseTag::set_data( SequenceManager* /*seqman*/, 00140 Error* error, 00141 const EntityHandle* /*entities*/, 00142 size_t /*num_entities*/, 00143 const void* /*data*/ ) 00144 { 00145 return not_var_len(error, get_name()); 00146 } 00147 00148 ErrorCode VarLenSparseTag::set_data( SequenceManager* /*seqman*/, 00149 Error* error, 00150 const Range& /*entities*/, 00151 const void* /*data */) 00152 { 00153 return not_var_len(error, get_name()); 00154 } 00155 00156 ErrorCode VarLenSparseTag::set_data( SequenceManager* seqman, 00157 Error* error, 00158 const EntityHandle* entities, 00159 size_t num_entities, 00160 void const* const* pointers, 00161 const int* lengths ) 00162 { 00163 ErrorCode rval = validate_lengths( error, lengths, num_entities ); 00164 if (MB_SUCCESS != rval) 00165 return rval; 00166 00167 rval = seqman->check_valid_entities( error, entities, num_entities, true ); 00168 if (MB_SUCCESS != rval) 00169 return rval; 00170 00171 for (size_t i = 0; i < num_entities; ++i) { 00172 if (lengths[i]) 00173 mData[entities[i]].set( pointers[i], lengths[i] ); 00174 else { 00175 MapType::iterator iter = mData.find(entities[i]); 00176 if (iter != mData.end()) { 00177 iter->second.clear(); 00178 mData.erase(iter); 00179 } 00180 } 00181 } 00182 return MB_SUCCESS; 00183 } 00184 00185 ErrorCode VarLenSparseTag::set_data( SequenceManager* seqman, 00186 Error* error, 00187 const Range& entities, 00188 void const* const* pointers, 00189 const int* lengths ) 00190 { 00191 ErrorCode rval = validate_lengths( error, lengths, entities.size() ); 00192 if (MB_SUCCESS != rval) 00193 return rval; 00194 00195 rval = seqman->check_valid_entities( error, entities ); 00196 if (MB_SUCCESS != rval) 00197 return rval; 00198 00199 Range::const_iterator i; 00200 for (i = entities.begin(); i != entities.end(); ++i, ++pointers, ++lengths) { 00201 if (*lengths) 00202 mData[*i].set( *pointers, *lengths ); 00203 else { 00204 MapType::iterator iter = mData.find(*i); 00205 if (iter != mData.end()) { 00206 iter->second.clear(); 00207 mData.erase(iter); 00208 } 00209 } 00210 } 00211 return MB_SUCCESS; 00212 } 00213 00214 ErrorCode VarLenSparseTag::clear_data( SequenceManager* seqman, 00215 Error* error, 00216 const EntityHandle* entities, 00217 size_t num_entities, 00218 const void* value_ptr, 00219 int value_len ) 00220 { 00221 if (0 == value_len) { 00222 remove_data( seqman, 0, entities, num_entities ); 00223 return MB_SUCCESS; 00224 } 00225 00226 ErrorCode rval = validate_lengths( error, &value_len, 1 ); 00227 if (MB_SUCCESS != rval) 00228 return rval; 00229 00230 rval = seqman->check_valid_entities( error, entities, num_entities, true ); 00231 if (MB_SUCCESS != rval) 00232 return rval; 00233 00234 for (size_t i = 0; i < num_entities; ++i) 00235 mData[entities[i]].set( value_ptr, value_len ); 00236 return MB_SUCCESS; 00237 } 00238 00239 ErrorCode VarLenSparseTag::clear_data( SequenceManager* seqman, 00240 Error* error, 00241 const Range& entities, 00242 const void* value_ptr, 00243 int value_len ) 00244 { 00245 if (0 == value_len) { 00246 remove_data( seqman, 0, entities ); 00247 return MB_SUCCESS; 00248 } 00249 00250 ErrorCode rval = validate_lengths( error, &value_len, 1 ); 00251 if (MB_SUCCESS != rval) 00252 return rval; 00253 00254 rval = seqman->check_valid_entities( error, entities ); 00255 if (MB_SUCCESS != rval) 00256 return rval; 00257 00258 Range::const_iterator i; 00259 for (i = entities.begin(); i != entities.end(); ++i) 00260 mData[*i].set( value_ptr, value_len ); 00261 00262 return MB_SUCCESS; 00263 } 00264 00265 ErrorCode VarLenSparseTag::remove_data( SequenceManager*, 00266 Error* error, 00267 const EntityHandle* entities, 00268 size_t num_entities ) 00269 { 00270 ErrorCode result = MB_SUCCESS; 00271 for (size_t i = 0; i < num_entities; ++i) { 00272 MapType::iterator p = mData.find(entities[i]); 00273 if (p == mData.end()) 00274 result = not_found(error, get_name(), entities[i]); 00275 else { 00276 p->second.clear(); 00277 mData.erase(p); 00278 } 00279 } 00280 return result; 00281 } 00282 00283 ErrorCode VarLenSparseTag::remove_data( SequenceManager*, 00284 Error* error, 00285 const Range& entities ) 00286 { 00287 ErrorCode result = MB_SUCCESS; 00288 for (Range::iterator i = entities.begin(); i != entities.end(); ++i) { 00289 MapType::iterator p = mData.find(*i); 00290 if (p == mData.end()) 00291 result = not_found(error, get_name(), *i); 00292 else { 00293 p->second.clear(); 00294 mData.erase(p); 00295 } 00296 } 00297 return result; 00298 } 00299 00300 ErrorCode VarLenSparseTag::tag_iterate( SequenceManager*, 00301 Error* error, 00302 Range::iterator&, 00303 const Range::iterator&, 00304 void*&, 00305 bool) 00306 { 00307 error->set_last_error( "Cannot iterate over variable-length tag data" ); 00308 return MB_VARIABLE_DATA_LENGTH; 00309 } 00310 00311 00312 template <class Container> static inline 00313 void get_tagged( const VarLenSparseTag::MapType& mData, 00314 EntityType type, 00315 Container& output_range ) 00316 { 00317 VarLenSparseTag::MapType::const_iterator iter; 00318 typename Container::iterator hint = output_range.begin(); 00319 if (MBMAXTYPE == type) { 00320 for (iter = mData.begin(); iter != mData.end(); ++iter) 00321 hint = output_range.insert( hint, iter->first ); 00322 } 00323 else { 00324 #ifdef HAVE_UNORDERED_MAP 00325 for (iter = mData.begin(); iter != mData.end(); ++iter) 00326 if (TYPE_FROM_HANDLE(iter->first) == type) 00327 hint = output_range.insert( hint, iter->first ); 00328 #else 00329 iter = mData.lower_bound( FIRST_HANDLE(type) ); 00330 VarLenSparseTag::MapType::const_iterator end = mData.lower_bound( LAST_HANDLE(type)+1 ); 00331 for (; iter != end; ++iter) 00332 hint = output_range.insert( hint, iter->first ); 00333 #endif 00334 } 00335 } 00336 00337 template <class Container> static inline 00338 void get_tagged( const VarLenSparseTag::MapType& mData, 00339 Range::const_iterator begin, 00340 Range::const_iterator end, 00341 Container& output_range ) 00342 { 00343 VarLenSparseTag::MapType::const_iterator iter; 00344 typename Container::iterator hint = output_range.begin(); 00345 for (Range::const_iterator i = begin; i != end; ++i) 00346 if (mData.find(*i) != mData.end()) 00347 hint = output_range.insert( hint, *i ); 00348 } 00349 00350 template <class Container> static inline 00351 void get_tagged( const VarLenSparseTag::MapType& mData, 00352 Container& entities, 00353 EntityType type, 00354 const Range* intersect ) 00355 00356 { 00357 if (!intersect) 00358 get_tagged<Container>( mData, type, entities ); 00359 else if (MBMAXTYPE == type) 00360 get_tagged<Container>( mData, intersect->begin(), intersect->end(), entities ); 00361 else { 00362 std::pair<Range::iterator,Range::iterator> r = intersect->equal_range(type); 00363 get_tagged<Container>( mData, r.first, r.second, entities ); 00364 } 00365 } 00366 00367 00369 ErrorCode VarLenSparseTag::get_tagged_entities( const SequenceManager*, 00370 Range& entities, 00371 EntityType type, 00372 const Range* intersect ) const 00373 { 00374 get_tagged( mData, entities, type, intersect ); 00375 return MB_SUCCESS; 00376 } 00377 00379 ErrorCode VarLenSparseTag::num_tagged_entities( const SequenceManager*, 00380 size_t& output_count, 00381 EntityType type, 00382 const Range* intersect ) const 00383 { 00384 InsertCount counter( output_count ); 00385 get_tagged( mData, counter, type, intersect ); 00386 output_count = counter.end(); 00387 return MB_SUCCESS; 00388 } 00389 00390 ErrorCode VarLenSparseTag::find_entities_with_value( 00391 const SequenceManager* seqman, 00392 Error*, 00393 Range& output_entities, 00394 const void* value, 00395 int value_bytes, 00396 const EntityType type, 00397 const Range* intersect_entities ) const 00398 { 00399 if (value_bytes && value_bytes != get_size()) 00400 return MB_INVALID_SIZE; 00401 00402 MapType::const_iterator iter, end; 00403 #ifdef HAVE_UNORDERED_MAP 00404 if (intersect_entities) { 00405 std::pair<Range::iterator,Range::iterator> r; 00406 if (type == MBMAXTYPE) { 00407 r.first = intersect_entities->begin(); 00408 r.second = intersect_entities->end(); 00409 } 00410 else { 00411 r = intersect_entities->equal_range( type ); 00412 } 00413 00414 00415 find_map_varlen_values_equal( *this, value, get_size(), 00416 r.first, r.second, 00417 mData, output_entities ); 00418 } 00419 else if (type == MBMAXTYPE) { 00420 find_tag_varlen_values_equal( *this, value, get_size(), 00421 mData.begin(), mData.end(), 00422 output_entities ); 00423 } 00424 else { 00425 Range tmp; 00426 seqman->get_entities( type, tmp ); 00427 find_map_varlen_values_equal( *this, value, get_size(), 00428 tmp.begin(), tmp.end(), 00429 mData, output_entities ); 00430 } 00431 #else 00432 if (intersect_entities) { 00433 for (Range::const_pair_iterator p = intersect_entities->begin(); 00434 p != intersect_entities->end(); ++p) { 00435 iter = mData.lower_bound( p->first ); 00436 end = mData.upper_bound( p->second ); 00437 find_tag_varlen_values_equal( *this, value, get_size(), iter, end, 00438 output_entities); 00439 } 00440 } 00441 else { 00442 if (type == MBMAXTYPE) { 00443 iter = mData.begin(); 00444 end = mData.end(); 00445 } 00446 else { 00447 iter = mData.lower_bound( CREATE_HANDLE( type, MB_START_ID ) ); 00448 end = mData.upper_bound( CREATE_HANDLE( type, MB_END_ID ) ); 00449 } 00450 find_tag_varlen_values_equal( *this, value, get_size(), iter, end, 00451 output_entities); 00452 } 00453 #endif 00454 00455 return MB_SUCCESS; 00456 } 00457 00458 bool VarLenSparseTag::is_tagged( const SequenceManager*, EntityHandle h ) const 00459 { 00460 return mData.find(h) != mData.end(); 00461 } 00462 00463 ErrorCode VarLenSparseTag::get_memory_use( const SequenceManager*, 00464 unsigned long& total, 00465 unsigned long& per_entity ) const 00466 00467 { 00468 total = mData.size() * (3*sizeof(void*) + sizeof(VarLenTag)); 00469 for (MapType::const_iterator i = mData.begin(); i != mData.end(); ++i) 00470 total += i->second.mem(); 00471 if (mData.size()) 00472 per_entity = total / mData.size(); 00473 total += sizeof(*this) + TagInfo::get_memory_use(); 00474 00475 return MB_SUCCESS; 00476 } 00477 00478 } // namespace moab 00479 00480 00481 00482