![]() |
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 "SparseTag.hpp"
00020 #include "moab/Range.hpp"
00021 #include "TagCompare.hpp"
00022 #include "SysUtil.hpp"
00023 #include "SequenceManager.hpp"
00024 #include "moab/Error.hpp"
00025 #include "moab/ErrorHandler.hpp"
00026 #include "moab/CN.hpp"
00027
00028 namespace moab
00029 {
00030
00031 SparseTag::SparseTag( const char* name, int size, DataType type, const void* default_value )
00032 : TagInfo( name, size, type, default_value, size )
00033 {
00034 }
00035
00036 SparseTag::~SparseTag()
00037 {
00038 release_all_data( 0, 0, true );
00039 }
00040
00041 TagType SparseTag::get_storage_type() const
00042 {
00043 return MB_TAG_SPARSE;
00044 }
00045
00046 ErrorCode SparseTag::release_all_data( SequenceManager*, Error*, bool )
00047 {
00048 for( MapType::iterator i = mData.begin(); i != mData.end(); ++i )
00049 mAllocator.destroy( i->second );
00050 mData.clear();
00051 return MB_SUCCESS;
00052 }
00053
00054 ErrorCode SparseTag::set_data( Error*, EntityHandle entity_handle, const void* data )
00055 {
00056 #ifdef MOAB_HAVE_UNORDERED_MAP
00057 MapType::iterator iter = mData.find( entity_handle );
00058 #else
00059 MapType::iterator iter = mData.lower_bound( entity_handle );
00060 #endif
00061
00062 // Data space already exists
00063 if( iter != mData.end() && iter->first == entity_handle ) memcpy( iter->second, data, get_size() );
00064 // We need to make some data space
00065 else
00066 {
00067 void* new_data = allocate_data( entity_handle, iter, false );
00068 memcpy( new_data, data, get_size() );
00069 }
00070
00071 return MB_SUCCESS;
00072 }
00073
00074 ErrorCode SparseTag::get_data_ptr( EntityHandle entity_handle, const void*& ptr, bool allocate ) const
00075 {
00076 MapType::const_iterator iter = mData.find( entity_handle );
00077
00078 if( iter != mData.end() )
00079 ptr = iter->second;
00080 else if( get_default_value() && allocate )
00081 ptr = const_cast< SparseTag* >( this )->allocate_data( entity_handle, iter, allocate );
00082 else
00083 return MB_FAILURE;
00084
00085 return MB_SUCCESS;
00086 }
00087
00088 ErrorCode SparseTag::get_data( Error* /* error */, EntityHandle entity_handle, void* data ) const
00089 {
00090 const void* ptr = 0;
00091 ErrorCode rval = get_data_ptr( entity_handle, ptr, false );
00092 if( MB_SUCCESS == rval )
00093 {
00094 memcpy( data, ptr, get_size() );
00095 return rval;
00096 }
00097 else if( get_default_value() )
00098 {
00099 memcpy( data, get_default_value(), get_size() );
00100 return MB_SUCCESS;
00101 }
00102 else
00103 return MB_TAG_NOT_FOUND;
00104 }
00105
00106 ErrorCode SparseTag::remove_data( Error* /* error */, EntityHandle entity_handle )
00107 {
00108 MapType::iterator i = mData.find( entity_handle );
00109 if( i == mData.end() ) return MB_TAG_NOT_FOUND;
00110
00111 mAllocator.destroy( i->second );
00112 mData.erase( i );
00113
00114 return MB_SUCCESS;
00115 }
00116
00117 ErrorCode SparseTag::get_data( const SequenceManager*,
00118 Error* /* error */,
00119 const EntityHandle* entities,
00120 size_t num_entities,
00121 void* data ) const
00122 {
00123 ErrorCode rval;
00124 unsigned char* ptr = reinterpret_cast< unsigned char* >( data );
00125 for( size_t i = 0; i < num_entities; ++i, ptr += get_size() )
00126 {
00127 rval = get_data( NULL, entities[i], ptr );
00128 if( MB_SUCCESS != rval ) return rval;
00129 }
00130
00131 return MB_SUCCESS;
00132 }
00133
00134 ErrorCode SparseTag::get_data( const SequenceManager*, Error* /* error */, const Range& entities, void* data ) const
00135 {
00136 ErrorCode rval;
00137 unsigned char* ptr = reinterpret_cast< unsigned char* >( data );
00138 Range::const_iterator i;
00139 for( i = entities.begin(); i != entities.end(); ++i, ptr += get_size() )
00140 {
00141 rval = get_data( NULL, *i, ptr );
00142 if( MB_SUCCESS != rval ) return rval;
00143 }
00144
00145 return MB_SUCCESS;
00146 }
00147
00148 ErrorCode SparseTag::get_data( const SequenceManager*,
00149 Error* /* error */,
00150 const EntityHandle* entities,
00151 size_t num_entities,
00152 const void** pointers,
00153 int* data_lengths ) const
00154 {
00155 if( data_lengths )
00156 {
00157 int len = get_size();
00158 SysUtil::setmem( data_lengths, &len, sizeof( int ), num_entities );
00159 }
00160
00161 ErrorCode rval = MB_SUCCESS, rval_tmp;
00162 for( size_t i = 0; i < num_entities; ++i, ++pointers )
00163 {
00164 rval_tmp = get_data_ptr( entities[i], *pointers );
00165 if( MB_SUCCESS != rval_tmp && get_default_value() )
00166 {
00167 *pointers = get_default_value();
00168 }
00169 else if( MB_SUCCESS != rval_tmp )
00170 {
00171 return MB_TAG_NOT_FOUND;
00172 }
00173 }
00174
00175 return rval;
00176 }
00177
00178 ErrorCode SparseTag::get_data( const SequenceManager*,
00179 Error* /* error */,
00180 const Range& entities,
00181 const void** pointers,
00182 int* data_lengths ) const
00183 {
00184 if( data_lengths )
00185 {
00186 int len = get_size();
00187 SysUtil::setmem( data_lengths, &len, sizeof( int ), entities.size() );
00188 }
00189
00190 ErrorCode rval = MB_SUCCESS, rval_tmp;
00191 Range::const_iterator i;
00192 for( i = entities.begin(); i != entities.end(); ++i, ++pointers )
00193 {
00194 rval_tmp = get_data_ptr( *i, *pointers );
00195 if( MB_SUCCESS != rval_tmp && get_default_value() )
00196 {
00197 *pointers = get_default_value();
00198 }
00199 else if( MB_SUCCESS != rval_tmp )
00200 {
00201 return MB_TAG_NOT_FOUND;
00202 }
00203 }
00204
00205 return rval;
00206 }
00207
00208 ErrorCode SparseTag::set_data( SequenceManager* seqman,
00209 Error* /* error */,
00210 const EntityHandle* entities,
00211 size_t num_entities,
00212 const void* data )
00213 {
00214 ErrorCode rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
00215
00216 const unsigned char* ptr = reinterpret_cast< const unsigned char* >( data );
00217 for( size_t i = 0; i < num_entities; ++i, ptr += get_size() )
00218 {
00219 rval = set_data( NULL, entities[i], ptr );MB_CHK_ERR( rval );
00220 }
00221
00222 return MB_SUCCESS;
00223 }
00224
00225 ErrorCode SparseTag::set_data( SequenceManager* seqman, Error* /* error */, const Range& entities, const void* data )
00226 {
00227 ErrorCode rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
00228
00229 const unsigned char* ptr = reinterpret_cast< const unsigned char* >( data );
00230 Range::const_iterator i;
00231 for( i = entities.begin(); i != entities.end(); ++i, ptr += get_size() )
00232 if( MB_SUCCESS != ( rval = set_data( NULL, *i, ptr ) ) ) return rval;
00233
00234 return MB_SUCCESS;
00235 }
00236
00237 ErrorCode SparseTag::set_data( SequenceManager* seqman,
00238 Error* /* error */,
00239 const EntityHandle* entities,
00240 size_t num_entities,
00241 void const* const* pointers,
00242 const int* lengths )
00243 {
00244 ErrorCode rval = validate_lengths( NULL, lengths, num_entities );MB_CHK_ERR( rval );
00245
00246 rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
00247
00248 for( size_t i = 0; i < num_entities; ++i, ++pointers )
00249 {
00250 rval = set_data( NULL, entities[i], *pointers );MB_CHK_ERR( rval );
00251 }
00252
00253 return MB_SUCCESS;
00254 }
00255
00256 ErrorCode SparseTag::set_data( SequenceManager* seqman,
00257 Error* /* error */,
00258 const Range& entities,
00259 void const* const* pointers,
00260 const int* lengths )
00261 {
00262 ErrorCode rval = validate_lengths( NULL, lengths, entities.size() );MB_CHK_ERR( rval );
00263
00264 rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
00265
00266 Range::const_iterator i;
00267 for( i = entities.begin(); i != entities.end(); ++i, ++pointers )
00268 {
00269 rval = set_data( NULL, *i, *pointers );MB_CHK_ERR( rval );
00270 }
00271
00272 return MB_SUCCESS;
00273 }
00274
00275 ErrorCode SparseTag::clear_data( SequenceManager* seqman,
00276 Error* /* error */,
00277 const EntityHandle* entities,
00278 size_t num_entities,
00279 const void* value_ptr,
00280 int value_len )
00281 {
00282 if( value_len && value_len != get_size() )
00283 {
00284 MB_SET_ERR( MB_INVALID_SIZE, "Invalid data size " << get_size() << " specified for sparse tag " << get_name()
00285 << " of size " << value_len );
00286 }
00287
00288 ErrorCode rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
00289
00290 for( size_t i = 0; i < num_entities; ++i )
00291 {
00292 rval = set_data( NULL, entities[i], value_ptr );MB_CHK_ERR( rval );
00293 }
00294
00295 return MB_SUCCESS;
00296 }
00297
00298 ErrorCode SparseTag::clear_data( SequenceManager* seqman,
00299 Error* /* error */,
00300 const Range& entities,
00301 const void* value_ptr,
00302 int value_len )
00303 {
00304 if( value_len && value_len != get_size() )
00305 {
00306 MB_SET_ERR( MB_INVALID_SIZE, "Invalid data size " << get_size() << " specified for sparse tag " << get_name()
00307 << " of size " << value_len );
00308 }
00309
00310 ErrorCode rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
00311
00312 Range::const_iterator i;
00313 for( i = entities.begin(); i != entities.end(); ++i )
00314 {
00315 rval = set_data( NULL, *i, value_ptr );MB_CHK_ERR( rval );
00316 }
00317
00318 return MB_SUCCESS;
00319 }
00320
00321 ErrorCode SparseTag::remove_data( SequenceManager*,
00322 Error* /* error */,
00323 const EntityHandle* entities,
00324 size_t num_entities )
00325 {
00326 ErrorCode rval;
00327 for( size_t i = 0; i < num_entities; ++i )
00328 {
00329 rval = remove_data( NULL, entities[i] );
00330 if( MB_SUCCESS != rval ) return rval;
00331 }
00332
00333 return MB_SUCCESS;
00334 }
00335
00336 ErrorCode SparseTag::remove_data( SequenceManager*, Error* /* error */, const Range& entities )
00337 {
00338 for( Range::const_iterator i = entities.begin(); i != entities.end(); ++i )
00339 if( MB_SUCCESS != remove_data( NULL, *i ) ) return MB_TAG_NOT_FOUND;
00340
00341 return MB_SUCCESS;
00342 }
00343
00344 ErrorCode SparseTag::tag_iterate( SequenceManager* seqman,
00345 Error* /* error */,
00346 Range::iterator& iter,
00347 const Range::iterator& end,
00348 void*& data_ptr,
00349 bool allocate )
00350 {
00351 // Note: We are asked to returning a block of contiguous storage
00352 // for some block of contiguous handles for which the tag
00353 // storage is also contiguous. As sparse tag storage is
00354 // never contiguous, all we can do is return a pointer to the
00355 // data for the first entity.
00356
00357 // If asked for nothing, successfully return nothing.
00358 if( iter == end ) return MB_SUCCESS;
00359
00360 // Note: get_data_ptr will return the default value if the
00361 // handle is not found, so test to make sure that the
00362 // handle is valid.
00363 ErrorCode rval = seqman->check_valid_entities( NULL, &*iter, 1 );MB_CHK_ERR( rval );
00364
00365 // Get pointer to tag storage for entity pointed to by iter
00366 const void* ptr = NULL;
00367 rval = get_data_ptr( *iter, ptr );
00368 if( MB_SUCCESS == rval )
00369 data_ptr = const_cast< void* >( ptr );
00370 else if( get_default_value() && allocate )
00371 {
00372 ptr = allocate_data( *iter, mData.end() );
00373 data_ptr = const_cast< void* >( ptr );
00374 }
00375 else
00376 {
00377 // If allocation was not requested, need to increment the iterator so that
00378 // the count can be computed properly
00379 if( get_default_value() && !allocate ) ++iter;
00380 // return not_found(get_name(), *iter);
00381 }
00382
00383 // Increment iterator and return
00384 ++iter;
00385 return MB_SUCCESS;
00386 }
00387
00388 template < class Container >
00389 static inline void get_tagged( const SparseTag::MapType& mData, EntityType type, Container& output_range )
00390 {
00391 SparseTag::MapType::const_iterator iter;
00392 typename Container::iterator hint = output_range.begin();
00393 if( MBMAXTYPE == type )
00394 {
00395 for( iter = mData.begin(); iter != mData.end(); ++iter )
00396 hint = output_range.insert( hint, iter->first );
00397 }
00398 else
00399 {
00400 #ifdef MOAB_HAVE_UNORDERED_MAP
00401 for( iter = mData.begin(); iter != mData.end(); ++iter )
00402 if( TYPE_FROM_HANDLE( iter->first ) == type ) hint = output_range.insert( hint, iter->first );
00403 #else
00404 iter = mData.lower_bound( FIRST_HANDLE( type ) );
00405 SparseTag::MapType::const_iterator end = mData.lower_bound( LAST_HANDLE( type ) + 1 );
00406 for( ; iter != end; ++iter )
00407 hint = output_range.insert( hint, iter->first );
00408 #endif
00409 }
00410 }
00411
00412 template < class Container >
00413 static inline void get_tagged( const SparseTag::MapType& mData,
00414 Range::const_iterator begin,
00415 Range::const_iterator end,
00416 Container& output_range )
00417 {
00418 typename Container::iterator hint = output_range.begin();
00419 for( Range::const_iterator i = begin; i != end; ++i )
00420 if( mData.find( *i ) != mData.end() ) hint = output_range.insert( hint, *i );
00421 }
00422
00423 template < class Container >
00424 static inline void get_tagged( const SparseTag::MapType& mData,
00425 Container& entities,
00426 EntityType type,
00427 const Range* intersect )
00428 {
00429 if( !intersect )
00430 get_tagged< Container >( mData, type, entities );
00431 else if( MBMAXTYPE == type )
00432 get_tagged< Container >( mData, intersect->begin(), intersect->end(), entities );
00433 else
00434 {
00435 std::pair< Range::iterator, Range::iterator > r = intersect->equal_range( type );
00436 get_tagged< Container >( mData, r.first, r.second, entities );
00437 }
00438 }
00439
00440 //! Gets all entity handles that match a type and tag
00441 ErrorCode SparseTag::get_tagged_entities( const SequenceManager*,
00442 Range& output_range,
00443 EntityType type,
00444 const Range* intersect ) const
00445 {
00446 get_tagged( mData, output_range, type, intersect );
00447 return MB_SUCCESS;
00448 }
00449
00450 //! Gets all entity handles that match a type and tag
00451 ErrorCode SparseTag::num_tagged_entities( const SequenceManager*,
00452 size_t& output_count,
00453 EntityType type,
00454 const Range* intersect ) const
00455 {
00456 InsertCount counter( output_count );
00457 get_tagged( mData, counter, type, intersect );
00458 output_count = counter.end();
00459 return MB_SUCCESS;
00460 }
00461
00462 ErrorCode SparseTag::find_entities_with_value(
00463 #ifdef MOAB_HAVE_UNORDERED_MAP
00464 const SequenceManager* seqman,
00465 #else
00466 const SequenceManager*,
00467 #endif
00468 Error* /* error */,
00469 Range& output_entities,
00470 const void* value,
00471 int value_bytes,
00472 EntityType type,
00473 const Range* intersect_entities ) const
00474 {
00475 if( value_bytes && value_bytes != get_size() )
00476 {
00477 MB_SET_ERR( MB_INVALID_SIZE, "Invalid data size " << get_size() << " specified for sparse tag " << get_name()
00478 << " of size " << value_bytes );
00479 }
00480
00481 MapType::const_iterator iter, end;
00482 #ifdef MOAB_HAVE_UNORDERED_MAP
00483 if( intersect_entities )
00484 {
00485 std::pair< Range::iterator, Range::iterator > r;
00486 if( type == MBMAXTYPE )
00487 {
00488 r.first = intersect_entities->begin();
00489 r.second = intersect_entities->end();
00490 }
00491 else
00492 {
00493 r = intersect_entities->equal_range( type );
00494 }
00495
00496 find_map_values_equal( *this, value, get_size(), r.first, r.second, mData, output_entities );
00497 }
00498 else if( type == MBMAXTYPE )
00499 {
00500 find_tag_values_equal( *this, value, get_size(), mData.begin(), mData.end(), output_entities );
00501 }
00502 else
00503 {
00504 Range tmp;
00505 seqman->get_entities( type, tmp );
00506 find_map_values_equal( *this, value, get_size(), tmp.begin(), tmp.end(), mData, output_entities );
00507 }
00508 #else
00509 if( intersect_entities )
00510 {
00511 for( Range::const_pair_iterator p = intersect_entities->begin(); p != intersect_entities->end(); ++p )
00512 {
00513 iter = mData.lower_bound( p->first );
00514 end = mData.upper_bound( p->second );
00515 find_tag_values_equal( *this, value, get_size(), iter, end, output_entities );
00516 }
00517 }
00518 else
00519 {
00520 if( type == MBMAXTYPE )
00521 {
00522 iter = mData.begin();
00523 end = mData.end();
00524 }
00525 else
00526 {
00527 iter = mData.lower_bound( CREATE_HANDLE( type, MB_START_ID ) );
00528 end = mData.upper_bound( CREATE_HANDLE( type, MB_END_ID ) );
00529 }
00530 find_tag_values_equal( *this, value, get_size(), iter, end, output_entities );
00531 }
00532 #endif
00533
00534 return MB_SUCCESS;
00535 }
00536
00537 bool SparseTag::is_tagged( const SequenceManager*, EntityHandle h ) const
00538 {
00539 return mData.find( h ) != mData.end();
00540 }
00541
00542 ErrorCode SparseTag::get_memory_use( const SequenceManager*, unsigned long& total, unsigned long& per_entity ) const
00543
00544 {
00545 per_entity = get_size() + 4 * sizeof( void* );
00546 total = ( mData.size() * per_entity ) + sizeof( *this ) + TagInfo::get_memory_use();
00547
00548 return MB_SUCCESS;
00549 }
00550
00551 } // namespace moab