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