Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
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 */,
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines