![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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
00017 #include
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