MOAB: Mesh Oriented datABase  (version 5.2.1)
VarLenDenseTag.cpp
Go to the documentation of this file.
00001 /** \file   VarLenDenseTag.cpp
00002  *  \author Jason Kraftcheck
00003  *  \date   2010-12-14
00004  */
00005 
00006 #include "VarLenDenseTag.hpp"
00007 #include "moab/Range.hpp"
00008 #include "TagCompare.hpp"
00009 #include "SysUtil.hpp"
00010 #include "SequenceManager.hpp"
00011 #include "SequenceData.hpp"
00012 #include "RangeSeqIntersectIter.hpp"
00013 #include "moab/Error.hpp"
00014 #include "moab/ErrorHandler.hpp"
00015 #include "moab/CN.hpp"
00016 #include <utility>
00017 
00018 namespace moab
00019 {
00020 
00021 inline static ErrorCode not_found( std::string /*name*/, EntityHandle /*h*/ )
00022 {
00023 #if 0
00024   // MB_TAG_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
00025   // Print warning messages for debugging only
00026   if (h)
00027     fprintf(stderr, "[Warning]: No variable-length dense tag %s value for %s %lu\n",
00028         name.c_str(),
00029         CN::EntityTypeName(TYPE_FROM_HANDLE(h)),
00030         (unsigned long)ID_FROM_HANDLE(h));
00031   else
00032     fprintf(stderr, "[Warning]: No variable-length dense tag %s value for root set\n", name.c_str());
00033 #endif
00034 
00035     return MB_TAG_NOT_FOUND;
00036 }
00037 
00038 VarLenDenseTag::VarLenDenseTag( int index, const char* name, DataType type, const void* default_value,
00039                                 int default_value_size )
00040     : TagInfo( name, MB_VARIABLE_LENGTH, type, default_value, default_value_size ), mySequenceArray( index )
00041 {
00042 }
00043 
00044 VarLenDenseTag* VarLenDenseTag::create_tag( SequenceManager* seqman, Error* error, const char* name, DataType type,
00045                                             const void* default_value, int default_value_size )
00046 {
00047     int index;
00048     if( MB_SUCCESS != seqman->reserve_tag_array( error, MB_VARIABLE_LENGTH, index ) ) return NULL;
00049 
00050     return new VarLenDenseTag( index, name, type, default_value, default_value_size );
00051 }
00052 
00053 VarLenDenseTag::~VarLenDenseTag()
00054 {
00055     assert( mySequenceArray < 0 );
00056 }
00057 
00058 TagType VarLenDenseTag::get_storage_type() const
00059 {
00060     return MB_TAG_DENSE;
00061 }
00062 
00063 ErrorCode VarLenDenseTag::release_all_data( SequenceManager* seqman, Error* error, bool delete_pending )
00064 {
00065     Range all_ents;
00066     seqman->get_entities( all_ents );
00067     ErrorCode rval = remove_data( seqman, error, all_ents );
00068     if( MB_SUCCESS == rval )
00069     {
00070         rval = seqman->release_tag_array( error, mySequenceArray, delete_pending );
00071         if( MB_SUCCESS == rval && delete_pending ) mySequenceArray = -1;
00072     }
00073 
00074     return rval;
00075 }
00076 
00077 ErrorCode VarLenDenseTag::get_array( const SequenceManager* seqman, Error* /* error */, EntityHandle h,
00078                                      const VarLenTag*& ptr, size_t& count ) const
00079 {
00080     const EntitySequence* seq = NULL;
00081     ErrorCode rval            = seqman->find( h, seq );
00082     if( MB_SUCCESS != rval )
00083     {
00084         if( !h )
00085         {  // Root set
00086             ptr   = &meshValue;
00087             count = 1;
00088             return MB_SUCCESS;
00089         }
00090         else
00091         {
00092             ptr   = NULL;
00093             count = 0;
00094             return not_found( get_name(), h );
00095         }
00096     }
00097 
00098     const void* mem = seq->data()->get_tag_data( mySequenceArray );
00099     ptr             = reinterpret_cast< const VarLenTag* >( mem );
00100     count           = seq->data()->end_handle() - h + 1;
00101     if( ptr ) ptr += h - seq->data()->start_handle();
00102 
00103     return MB_SUCCESS;
00104 }
00105 
00106 ErrorCode VarLenDenseTag::get_array( SequenceManager* seqman, Error* /* error */, EntityHandle h, VarLenTag*& ptr,
00107                                      size_t& count, bool allocate )
00108 {
00109     EntitySequence* seq = NULL;
00110     ErrorCode rval      = seqman->find( h, seq );
00111     if( MB_SUCCESS != rval )
00112     {
00113         if( !h )
00114         {  // Root set
00115             ptr   = &meshValue;
00116             count = 1;
00117             return MB_SUCCESS;
00118         }
00119         else
00120         {
00121             ptr   = NULL;
00122             count = 0;
00123             return not_found( get_name(), h );
00124         }
00125     }
00126 
00127     void* mem = seq->data()->get_tag_data( mySequenceArray );
00128     if( !mem && allocate )
00129     {
00130         mem = seq->data()->allocate_tag_array( mySequenceArray, sizeof( VarLenTag ) );
00131         if( !mem )
00132         { MB_SET_ERR( MB_MEMORY_ALLOCATION_FAILED, "Memory allocation for variable-length dense tag data failed" ); }
00133 
00134         memset( mem, 0, sizeof( VarLenTag ) * seq->data()->size() );
00135     }
00136 
00137     ptr   = reinterpret_cast< VarLenTag* >( mem );
00138     count = seq->data()->end_handle() - h + 1;
00139     if( ptr ) ptr += h - seq->data()->start_handle();
00140 
00141     return MB_SUCCESS;
00142 }
00143 
00144 ErrorCode VarLenDenseTag::get_data( const SequenceManager*, Error* /* error */, const EntityHandle*, size_t,
00145                                     void* ) const
00146 {
00147     MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00148 }
00149 
00150 ErrorCode VarLenDenseTag::get_data( const SequenceManager*, Error* /* error */, const Range&, void* ) const
00151 {
00152     MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00153 }
00154 
00155 ErrorCode VarLenDenseTag::get_data( const SequenceManager* seqman, Error* /* error */, const EntityHandle* entities,
00156                                     size_t num_entities, const void** pointers, int* lengths ) const
00157 {
00158     if( !lengths )
00159     { MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" ); }
00160 
00161     ErrorCode result              = MB_SUCCESS, rval;
00162     const EntityHandle* const end = entities + num_entities;
00163     size_t junk                   = 0;
00164     const VarLenTag* ptr          = NULL;
00165 
00166     for( const EntityHandle* i = entities; i != end; ++i, ++pointers, ++lengths )
00167     {
00168         rval = get_array( seqman, NULL, *i, ptr, junk );MB_CHK_ERR( rval );
00169 
00170         if( ptr && ptr->size() )
00171         {
00172             *pointers = ptr->data();
00173             *lengths  = ptr->size();
00174         }
00175         else if( get_default_value() )
00176         {
00177             *pointers = get_default_value();
00178             *lengths  = get_default_value_size();
00179         }
00180         else
00181         {
00182             *pointers = 0;
00183             *lengths  = 0;
00184             result    = not_found( get_name(), *i );
00185         }
00186     }
00187 
00188     return result;
00189 }
00190 
00191 ErrorCode VarLenDenseTag::get_data( const SequenceManager* seqman, Error* /* error */, const Range& entities,
00192                                     const void** pointers, int* lengths ) const
00193 {
00194     if( !lengths )
00195     { MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" ); }
00196 
00197     ErrorCode rval;
00198     size_t avail           = 0;
00199     const VarLenTag* array = NULL;
00200 
00201     for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00202     {
00203         EntityHandle start = p->first;
00204         while( start <= p->second )
00205         {
00206             rval = get_array( seqman, NULL, start, array, avail );MB_CHK_ERR( rval );
00207 
00208             const size_t count = std::min< size_t >( p->second - start + 1, avail );
00209 
00210             if( !array )
00211             {
00212                 const void* defval = get_default_value();
00213                 const int len      = get_default_value_size();
00214                 SysUtil::setmem( pointers, &defval, sizeof( void* ), count );
00215                 SysUtil::setmem( lengths, &len, sizeof( int ), count );
00216                 pointers += count;
00217                 lengths += count;
00218                 if( !defval ) return not_found( get_name(), start );
00219             }
00220 
00221             const VarLenTag* end_data = array + count;
00222             while( array != end_data )
00223             {
00224                 if( array->size() )
00225                 {
00226                     *pointers = array->data();
00227                     *lengths  = array->size();
00228                 }
00229                 else if( get_default_value() )
00230                 {
00231                     *pointers = get_default_value();
00232                     *lengths  = get_default_value_size();
00233                 }
00234                 else
00235                 {
00236                     *pointers = NULL;
00237                     *lengths  = 0;
00238                     return not_found( get_name(), start );
00239                 }
00240                 ++pointers;
00241                 ++lengths;
00242                 ++array;
00243                 ++start;
00244             }
00245         }
00246     }
00247 
00248     return MB_SUCCESS;
00249 }
00250 
00251 ErrorCode VarLenDenseTag::set_data( SequenceManager*, Error* /* error */, const EntityHandle*, size_t, const void* )
00252 {
00253     MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00254 }
00255 
00256 ErrorCode VarLenDenseTag::set_data( SequenceManager*, Error* /* error */, const Range&, const void* )
00257 {
00258     MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
00259 }
00260 
00261 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman, Error* /* error */, const EntityHandle* entities,
00262                                     size_t num_entities, bool one_value, void const* const* pointers,
00263                                     const int* lengths )
00264 {
00265     ErrorCode rval = validate_lengths( NULL, lengths, one_value ? 1 : num_entities );MB_CHK_ERR( rval );
00266 
00267     const EntityHandle* const end = entities + num_entities;
00268     VarLenTag* array              = NULL;
00269     size_t junk                   = 0;
00270     const size_t step             = one_value ? 0 : 1;
00271 
00272     for( const EntityHandle* i = entities; i != end; ++i )
00273     {
00274         rval = get_array( seqman, NULL, *i, array, junk, true );MB_CHK_ERR( rval );
00275 
00276         array->set( *pointers, *lengths );
00277         pointers += step;
00278         lengths += step;
00279     }
00280 
00281     return MB_SUCCESS;
00282 }
00283 
00284 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman, Error* /* error */, const Range& entities, bool one_value,
00285                                     void const* const* pointers, const int* lengths )
00286 {
00287     ErrorCode rval = validate_lengths( NULL, lengths, one_value ? 1 : entities.size() );MB_CHK_ERR( rval );
00288 
00289     VarLenTag* array  = NULL;
00290     size_t avail      = 0;
00291     const size_t step = one_value ? 0 : 1;
00292 
00293     for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00294     {
00295         EntityHandle start = p->first;
00296         while( start <= p->second )
00297         {
00298             rval = get_array( seqman, NULL, start, array, avail, true );MB_CHK_ERR( rval );
00299 
00300             const EntityHandle end = std::min< EntityHandle >( p->second + 1, start + avail );
00301             while( start != end )
00302             {
00303                 array->set( *pointers, *lengths );
00304                 ++start;
00305                 ++array;
00306                 pointers += step;
00307                 lengths += step;
00308             }
00309         }
00310     }
00311 
00312     return MB_SUCCESS;
00313 }
00314 
00315 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman, Error* /* error */, const EntityHandle* entities,
00316                                     size_t num_entities, void const* const* pointers, const int* lengths )
00317 {
00318     return set_data( seqman, NULL, entities, num_entities, false, pointers, lengths );
00319 }
00320 
00321 ErrorCode VarLenDenseTag::set_data( SequenceManager* seqman, Error* /* error */, const Range& entities,
00322                                     void const* const* pointers, const int* lengths )
00323 {
00324     return set_data( seqman, NULL, entities, false, pointers, lengths );
00325 }
00326 
00327 ErrorCode VarLenDenseTag::clear_data( SequenceManager* seqman, Error* /* error */, const EntityHandle* entities,
00328                                       size_t num_entities, const void* value_ptr, int value_len )
00329 {
00330     if( !value_ptr || !value_len )
00331         return remove_data( seqman, NULL, entities, num_entities );
00332     else
00333         return set_data( seqman, NULL, entities, num_entities, true, &value_ptr, &value_len );
00334 }
00335 
00336 ErrorCode VarLenDenseTag::clear_data( SequenceManager* seqman, Error* /* error */, const Range& entities,
00337                                       const void* value_ptr, int value_len )
00338 {
00339     if( !value_ptr || !value_len )
00340         return remove_data( seqman, NULL, entities );
00341     else
00342         return set_data( seqman, NULL, entities, true, &value_ptr, &value_len );
00343 }
00344 
00345 ErrorCode VarLenDenseTag::remove_data( SequenceManager* seqman, Error* /* error */, const EntityHandle* entities,
00346                                        size_t num_entities )
00347 {
00348     const EntityHandle* const end = entities + num_entities;
00349     VarLenTag* array              = NULL;
00350     size_t junk                   = 0;
00351     ErrorCode rval;
00352 
00353     for( const EntityHandle* i = entities; i != end; ++i )
00354     {
00355         rval = get_array( seqman, NULL, *i, array, junk, false );MB_CHK_ERR( rval );
00356 
00357         if( array ) array->clear();
00358     }
00359 
00360     return MB_SUCCESS;
00361 }
00362 
00363 ErrorCode VarLenDenseTag::remove_data( SequenceManager* seqman, Error* /* error */, const Range& entities )
00364 {
00365     VarLenTag* array = NULL;
00366     size_t avail     = 0;
00367     ErrorCode rval;
00368 
00369     for( Range::const_pair_iterator p = entities.const_pair_begin(); p != entities.const_pair_end(); ++p )
00370     {
00371         EntityHandle start = p->first;
00372         while( start <= p->second )
00373         {
00374             rval = get_array( seqman, NULL, start, array, avail, false );MB_CHK_ERR( rval );
00375 
00376             const EntityHandle end = std::min< EntityHandle >( p->second + 1, start + avail );
00377             if( array )
00378             {
00379                 while( start != end )
00380                 {
00381                     array->clear();
00382                     ++start;
00383                     ++array;
00384                 }
00385             }
00386             else
00387             {
00388                 start = end;
00389             }
00390         }
00391     }
00392 
00393     return MB_SUCCESS;
00394 }
00395 
00396 ErrorCode VarLenDenseTag::tag_iterate( SequenceManager*, Error* /* error */, Range::iterator&, const Range::iterator&,
00397                                        void*&, bool )
00398 {
00399     MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "Cannot iterate over variable-length tag data" );
00400 }
00401 
00402 template < class Container >
00403 static inline ErrorCode get_tagged( const SequenceManager* seqman, int mySequenceArray, EntityType type,
00404                                     Container& entities )
00405 {
00406     typename Container::iterator hint         = entities.begin();
00407     std::pair< EntityType, EntityType > range = type_range( type );
00408     TypeSequenceManager::const_iterator i;
00409     const VarLenTag *data, *iter, *end;
00410     for( EntityType t = range.first; t != range.second; ++t )
00411     {
00412         const TypeSequenceManager& map = seqman->entity_map( t );
00413         for( i = map.begin(); i != map.end(); ++i )
00414         {
00415             data = reinterpret_cast< const VarLenTag* >( ( *i )->data()->get_tag_data( mySequenceArray ) );
00416             if( !data ) continue;
00417             end                 = data + ( *i )->end_handle() - ( *i )->data()->start_handle() + 1;
00418             iter                = data + ( *i )->start_handle() - ( *i )->data()->start_handle();
00419             EntityHandle handle = ( *i )->start_handle();
00420             for( ; iter != end; ++iter, ++handle )
00421                 if( iter->size() ) hint = entities.insert( hint, handle );
00422         }
00423     }
00424 
00425     return MB_SUCCESS;
00426 }
00427 
00428 template < class Container >
00429 static inline ErrorCode get_tagged( const SequenceManager* seqman, int mySequenceArray, Range::const_iterator begin,
00430                                     Range::const_iterator end, Container& entities )
00431 {
00432     typename Container::iterator hint = entities.begin();
00433     RangeSeqIntersectIter iter( const_cast< SequenceManager* >( seqman ) );
00434     ErrorCode rval = iter.init( begin, end );
00435     const VarLenTag* data;
00436     for( ; MB_SUCCESS == rval; rval = iter.step() )
00437     {
00438         data = reinterpret_cast< const VarLenTag* >( iter.get_sequence()->data()->get_tag_data( mySequenceArray ) );
00439         if( !data ) continue;
00440 
00441         data += iter.get_start_handle() - iter.get_sequence()->data()->start_handle();
00442         size_t count = iter.get_end_handle() - iter.get_start_handle() + 1;
00443         for( size_t i = 0; i < count; ++i )
00444             if( data[i].size() ) hint = entities.insert( hint, iter.get_start_handle() + i );
00445         rval = iter.step();
00446     }
00447 
00448     if( MB_FAILURE != rval )  // We get MB_FAILURE at iterator end
00449         return rval;
00450 
00451     return MB_SUCCESS;
00452 }
00453 
00454 template < class Container >
00455 static inline ErrorCode get_tagged( const SequenceManager* seqman, int mySequenceArray, Container& entities,
00456                                     EntityType type, const Range* intersect )
00457 {
00458     if( !intersect )
00459         return get_tagged< Container >( seqman, mySequenceArray, type, entities );
00460     else if( MBMAXTYPE == type )
00461         return get_tagged< Container >( seqman, mySequenceArray, intersect->begin(), intersect->end(), entities );
00462     else
00463     {
00464         std::pair< Range::iterator, Range::iterator > r = intersect->equal_range( type );
00465         return get_tagged< Container >( seqman, mySequenceArray, r.first, r.second, entities );
00466     }
00467 }
00468 
00469 ErrorCode VarLenDenseTag::get_tagged_entities( const SequenceManager* seqman, Range& entities, EntityType type,
00470                                                const Range* intersect ) const
00471 {
00472     return get_tagged( seqman, mySequenceArray, entities, type, intersect );
00473 }
00474 
00475 ErrorCode VarLenDenseTag::num_tagged_entities( const SequenceManager* seqman, size_t& output_count, EntityType type,
00476                                                const Range* intersect ) const
00477 {
00478     InsertCount counter( output_count );
00479     ErrorCode rval = get_tagged( seqman, mySequenceArray, counter, type, intersect );
00480     output_count   = counter.end();
00481     return rval;
00482 }
00483 
00484 ErrorCode VarLenDenseTag::find_entities_with_value( const SequenceManager* seqman, Error* error, Range& output_entities,
00485                                                     const void* value, int value_bytes, EntityType type,
00486                                                     const Range* intersect_entities ) const
00487 {
00488     if( !intersect_entities )
00489     {
00490         std::pair< EntityType, EntityType > range = type_range( type );
00491         TypeSequenceManager::const_iterator i;
00492         for( EntityType t = range.first; t != range.second; ++t )
00493         {
00494             const TypeSequenceManager& map = seqman->entity_map( t );
00495             for( i = map.begin(); i != map.end(); ++i )
00496             {
00497                 const void* data = ( *i )->data()->get_tag_data( mySequenceArray );
00498                 if( data )
00499                 {
00500                     ByteArrayIterator start( ( *i )->data()->start_handle(), data, *this );
00501                     ByteArrayIterator end( ( *i )->end_handle() + 1, 0, 0 );
00502                     start += ( *i )->start_handle() - ( *i )->data()->start_handle();
00503                     find_tag_varlen_values_equal( *this, value, value_bytes, start, end, output_entities );
00504                 }
00505             }
00506         }
00507     }
00508     else
00509     {
00510         const VarLenTag* array;
00511         size_t count;
00512         ErrorCode rval;
00513 
00514         Range::const_pair_iterator p = intersect_entities->begin();
00515         if( type != MBMAXTYPE )
00516         {
00517             p = intersect_entities->lower_bound( type );
00518             assert( TYPE_FROM_HANDLE( p->first ) == type );
00519         }
00520         for( ;
00521              p != intersect_entities->const_pair_end() && ( MBMAXTYPE == type || TYPE_FROM_HANDLE( p->first ) == type );
00522              ++p )
00523         {
00524             EntityHandle start = p->first;
00525             while( start <= p->second )
00526             {
00527                 rval = get_array( seqman, error, start, array, count );MB_CHK_ERR( rval );
00528 
00529                 if( p->second - start < count - 1 ) count = p->second - start + 1;
00530 
00531                 if( array )
00532                 {
00533                     ByteArrayIterator istart( start, array, *this );
00534                     ByteArrayIterator iend( start + count, 0, 0 );
00535                     find_tag_varlen_values_equal( *this, value, value_bytes, istart, iend, output_entities );
00536                 }
00537                 start += count;
00538             }
00539         }
00540     }
00541 
00542     return MB_SUCCESS;
00543 }
00544 
00545 bool VarLenDenseTag::is_tagged( const SequenceManager* seqman, EntityHandle h ) const
00546 {
00547     const VarLenTag* ptr = NULL;  // Initialize to get rid of warning
00548     size_t count;
00549     return ( MB_SUCCESS == get_array( seqman, 0, h, ptr, count ) ) && ( NULL != ptr ) && ( NULL != ptr->data() );
00550 }
00551 
00552 ErrorCode VarLenDenseTag::get_memory_use( const SequenceManager* seqman, unsigned long& total,
00553                                           unsigned long& per_entity ) const
00554 
00555 {
00556     total        = 0;
00557     per_entity   = 0;
00558     size_t count = 0;
00559     for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
00560     {
00561         const TypeSequenceManager& map = seqman->entity_map( t );
00562         const SequenceData* prev_data  = 0;
00563         for( TypeSequenceManager::const_iterator i = map.begin(); i != map.end(); ++i )
00564         {
00565             const void* mem = ( *i )->data()->get_tag_data( mySequenceArray );
00566             if( !mem ) continue;
00567 
00568             if( ( *i )->data() != prev_data )
00569             {
00570                 total += ( *i )->data()->size();
00571                 prev_data = ( *i )->data();
00572             }
00573 
00574             count += ( *i )->size();
00575             const VarLenTag* array = reinterpret_cast< const VarLenTag* >( mem );
00576             for( int j = 0; j < ( *i )->size(); ++j )
00577                 per_entity += array[j].mem();
00578         }
00579     }
00580     total *= sizeof( VarLenTag );
00581     total += per_entity + sizeof( *this ) + TagInfo::get_memory_use();
00582     total += meshValue.mem() + sizeof( meshValue );
00583     if( count ) per_entity /= count;
00584     per_entity += sizeof( VarLenTag );
00585 
00586     return MB_SUCCESS;
00587 }
00588 
00589 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines