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