moab
VarLenSparseTag.cpp
Go to the documentation of this file.
00001 
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/CN.hpp"
00025 
00026 namespace moab {
00027 
00028 static ErrorCode not_found( Error* error, std::string name, EntityHandle h )
00029 {
00030   if (error) {
00031     if (h)
00032       error->set_last_error( "No tag %s value for %s %lu", 
00033                              name.c_str(),
00034                              CN::EntityTypeName(TYPE_FROM_HANDLE(h)), 
00035                              (unsigned long)ID_FROM_HANDLE(h));
00036     else
00037       error->set_last_error( "No tag %s value for root set", name.c_str());
00038   }
00039   return MB_TAG_NOT_FOUND;
00040 }
00041 
00042 static ErrorCode not_var_len( Error* error, std::string name )
00043 {
00044   error->set_last_error( "No size specified for variable-length tag %s data", name.c_str());
00045   return MB_VARIABLE_DATA_LENGTH;
00046 }
00047 
00048 VarLenSparseTag::VarLenSparseTag( const char* name,
00049                                   DataType type,
00050                                   const void* default_value,
00051                                   int default_value_bytes )
00052   : TagInfo( name, MB_VARIABLE_LENGTH, type, default_value, default_value_bytes )
00053   { }
00054 
00055 VarLenSparseTag::~VarLenSparseTag()
00056   { release_all_data(0,0,true); }
00057 
00058 TagType VarLenSparseTag::get_storage_type() const 
00059   { return MB_TAG_SPARSE; }
00060 
00061 ErrorCode VarLenSparseTag::release_all_data( SequenceManager*, Error*, bool )
00062 {
00063   mData.clear();
00064   return MB_SUCCESS;
00065 }
00066 
00067 ErrorCode VarLenSparseTag::get_data_ptr( Error* error,
00068                                          EntityHandle entity_handle, 
00069                                          const void*& ptr,
00070                                          int& length ) const
00071 {
00072   MapType::const_iterator iter = mData.find(entity_handle);
00073 
00074   if (iter != mData.end()) {
00075     ptr = iter->second.data();
00076     length = iter->second.size();
00077   }
00078   else if (get_default_value()) {
00079     ptr = get_default_value();
00080     length = get_default_value_size();
00081   }
00082   else 
00083     return not_found(error, get_name(), entity_handle);
00084   
00085   return MB_SUCCESS;
00086 }
00087 
00088 ErrorCode VarLenSparseTag::get_data( const SequenceManager*,
00089                                      Error* error,
00090                                      const EntityHandle* ,
00091                                      size_t ,
00092                                      void*  ) const
00093 {
00094   return not_var_len(error, get_name());
00095 }
00096 
00097 ErrorCode VarLenSparseTag::get_data( const SequenceManager*,
00098                                      Error* error,
00099                                      const Range& /*entities*/,
00100                                      void* /*data */) const
00101 {
00102   return not_var_len(error, get_name());
00103 }
00104 
00105 ErrorCode VarLenSparseTag::get_data( const SequenceManager* ,
00106                                      Error* error,
00107                                      const EntityHandle* entities,
00108                                      size_t num_entities,
00109                                      const void** pointers,
00110                                      int* lengths ) const
00111 {
00112   if (!lengths)
00113     return not_var_len(error, get_name());
00114 
00115   ErrorCode rval;
00116   for (size_t i = 0; i < num_entities; ++i)
00117     if (MB_SUCCESS != (rval = get_data_ptr(error, entities[i], pointers[i], lengths[i])))
00118       return rval;
00119   return MB_SUCCESS;
00120 }
00121  
00122 ErrorCode VarLenSparseTag::get_data( const SequenceManager*,
00123                                      Error* error,
00124                                      const Range& entities,
00125                                      const void** pointers,
00126                                      int* lengths ) const
00127 {
00128   if (!lengths)
00129     return not_var_len(error, get_name());
00130 
00131   ErrorCode rval;
00132   Range::const_iterator i;
00133   for (i = entities.begin(); i != entities.end(); ++i, ++pointers, ++lengths)
00134     if (MB_SUCCESS != (rval = get_data_ptr(error, *i, *pointers, *lengths)))
00135       return rval;
00136   return MB_SUCCESS;
00137 }
00138 
00139 ErrorCode VarLenSparseTag::set_data( SequenceManager* /*seqman*/,
00140                                      Error* error,
00141                                      const EntityHandle* /*entities*/,
00142                                      size_t /*num_entities*/,
00143                                      const void* /*data*/ )
00144 {
00145   return not_var_len(error, get_name());
00146 }
00147 
00148 ErrorCode VarLenSparseTag::set_data( SequenceManager* /*seqman*/,
00149                                      Error* error,
00150                                      const Range& /*entities*/,
00151                                      const void* /*data */)
00152 {
00153   return not_var_len(error, get_name());
00154 }
00155 
00156 ErrorCode VarLenSparseTag::set_data( SequenceManager* seqman,
00157                                      Error* error,
00158                                      const EntityHandle* entities,
00159                                      size_t num_entities,
00160                                      void const* const* pointers,
00161                                      const int* lengths )
00162 {
00163   ErrorCode rval = validate_lengths( error, lengths, num_entities );
00164   if (MB_SUCCESS != rval)
00165     return rval;
00166     
00167   rval = seqman->check_valid_entities( error, entities, num_entities, true );
00168   if (MB_SUCCESS != rval)
00169     return rval;
00170   
00171   for (size_t i = 0; i < num_entities; ++i) {
00172     if (lengths[i])
00173       mData[entities[i]].set( pointers[i], lengths[i] );
00174     else {
00175       MapType::iterator iter = mData.find(entities[i]);
00176       if (iter != mData.end()) {
00177         iter->second.clear();
00178         mData.erase(iter);
00179       }
00180     }
00181   }
00182   return MB_SUCCESS;
00183 }
00184 
00185 ErrorCode VarLenSparseTag::set_data( SequenceManager* seqman,
00186                                      Error* error,
00187                                      const Range& entities,
00188                                      void const* const* pointers,
00189                                      const int* lengths )
00190 {
00191   ErrorCode rval = validate_lengths( error, lengths, entities.size() );
00192   if (MB_SUCCESS != rval)
00193     return rval;
00194     
00195   rval = seqman->check_valid_entities( error, entities );
00196   if (MB_SUCCESS != rval)
00197     return rval;
00198   
00199   Range::const_iterator i;
00200   for (i = entities.begin(); i != entities.end(); ++i, ++pointers, ++lengths) {
00201     if (*lengths)
00202       mData[*i].set( *pointers, *lengths );
00203     else {
00204       MapType::iterator iter = mData.find(*i);
00205       if (iter != mData.end()) {
00206         iter->second.clear();
00207         mData.erase(iter);
00208       }
00209     }
00210   }
00211   return MB_SUCCESS;
00212 }
00213 
00214 ErrorCode VarLenSparseTag::clear_data( SequenceManager* seqman,
00215                                        Error* error,
00216                                        const EntityHandle* entities,
00217                                        size_t num_entities,
00218                                        const void* value_ptr,
00219                                        int value_len )
00220 {
00221   if (0 == value_len) {
00222     remove_data( seqman, 0, entities, num_entities );
00223     return MB_SUCCESS;
00224   }
00225 
00226   ErrorCode rval = validate_lengths( error, &value_len, 1 );
00227   if (MB_SUCCESS != rval)
00228     return rval;
00229 
00230   rval = seqman->check_valid_entities( error, entities, num_entities, true );
00231   if (MB_SUCCESS != rval)
00232     return rval;
00233   
00234   for (size_t i = 0; i < num_entities; ++i)
00235     mData[entities[i]].set( value_ptr, value_len );
00236   return MB_SUCCESS;
00237 }
00238 
00239 ErrorCode VarLenSparseTag::clear_data( SequenceManager* seqman,
00240                                        Error* error,
00241                                        const Range& entities,
00242                                        const void* value_ptr,
00243                                        int value_len )
00244 {
00245   if (0 == value_len) {
00246     remove_data( seqman, 0, entities );
00247     return MB_SUCCESS;
00248   }
00249 
00250   ErrorCode rval = validate_lengths( error, &value_len, 1 );
00251   if (MB_SUCCESS != rval)
00252     return rval;
00253     
00254   rval = seqman->check_valid_entities( error, entities );
00255   if (MB_SUCCESS != rval)
00256     return rval;
00257   
00258   Range::const_iterator i;
00259   for (i = entities.begin(); i != entities.end(); ++i)
00260     mData[*i].set( value_ptr, value_len );
00261 
00262   return MB_SUCCESS;
00263 }
00264 
00265 ErrorCode VarLenSparseTag::remove_data( SequenceManager*,
00266                                         Error* error,
00267                                         const EntityHandle* entities,
00268                                         size_t num_entities )
00269 {
00270   ErrorCode result = MB_SUCCESS;
00271   for (size_t i = 0; i < num_entities; ++i) {
00272     MapType::iterator p = mData.find(entities[i]);
00273     if (p == mData.end())
00274       result = not_found(error, get_name(), entities[i]);
00275     else {
00276       p->second.clear();
00277       mData.erase(p);
00278     }
00279   }
00280   return result;
00281 }
00282 
00283 ErrorCode VarLenSparseTag::remove_data( SequenceManager*,
00284                                         Error* error,
00285                                         const Range& entities )
00286 {
00287   ErrorCode result = MB_SUCCESS;
00288   for (Range::iterator i = entities.begin(); i != entities.end(); ++i) {
00289     MapType::iterator p = mData.find(*i);
00290     if (p == mData.end())
00291       result = not_found(error, get_name(), *i);
00292     else {
00293       p->second.clear();
00294       mData.erase(p);
00295     }
00296   }
00297   return result;
00298 }
00299 
00300 ErrorCode VarLenSparseTag::tag_iterate( SequenceManager*,
00301                                         Error* error,
00302                                         Range::iterator&,
00303                                         const Range::iterator&,
00304                                         void*&,
00305                                         bool)
00306 {
00307   error->set_last_error( "Cannot iterate over variable-length tag data" );
00308   return MB_VARIABLE_DATA_LENGTH;
00309 }
00310 
00311 
00312 template <class Container> static inline
00313 void get_tagged( const VarLenSparseTag::MapType& mData,
00314                  EntityType type,
00315                  Container& output_range )
00316 {
00317   VarLenSparseTag::MapType::const_iterator iter;
00318   typename Container::iterator hint = output_range.begin();
00319   if (MBMAXTYPE == type) {
00320     for (iter = mData.begin(); iter != mData.end(); ++iter)
00321       hint = output_range.insert( hint, iter->first );
00322   }
00323   else {
00324 #ifdef HAVE_UNORDERED_MAP
00325     for (iter = mData.begin(); iter != mData.end(); ++iter)
00326       if (TYPE_FROM_HANDLE(iter->first) == type)
00327         hint = output_range.insert( hint, iter->first );    
00328 #else
00329     iter = mData.lower_bound( FIRST_HANDLE(type) );
00330     VarLenSparseTag::MapType::const_iterator end = mData.lower_bound( LAST_HANDLE(type)+1 );
00331     for (; iter != end; ++iter)
00332       hint = output_range.insert( hint, iter->first );
00333 #endif
00334   }
00335 }
00336 
00337 template <class Container> static inline
00338 void get_tagged( const VarLenSparseTag::MapType& mData,
00339                  Range::const_iterator begin,
00340                  Range::const_iterator end,
00341                  Container& output_range )
00342 {
00343   VarLenSparseTag::MapType::const_iterator iter;
00344   typename Container::iterator hint = output_range.begin();
00345   for (Range::const_iterator i = begin; i != end; ++i)
00346     if (mData.find(*i) != mData.end())
00347       hint = output_range.insert( hint, *i );
00348 }
00349 
00350 template <class Container> static inline 
00351 void get_tagged( const VarLenSparseTag::MapType& mData,
00352                  Container& entities,
00353                  EntityType type,
00354                  const Range* intersect )
00355 
00356 {
00357   if (!intersect)
00358     get_tagged<Container>( mData, type, entities );
00359   else if (MBMAXTYPE == type)
00360     get_tagged<Container>( mData, intersect->begin(), intersect->end(), entities );
00361   else {
00362     std::pair<Range::iterator,Range::iterator> r = intersect->equal_range(type);
00363     get_tagged<Container>( mData, r.first, r.second, entities );
00364   }
00365 }
00366 
00367 
00369 ErrorCode VarLenSparseTag::get_tagged_entities( const SequenceManager*,
00370                                                 Range& entities,
00371                                                 EntityType type,
00372                                                 const Range* intersect ) const
00373 {
00374   get_tagged( mData, entities, type, intersect );
00375   return MB_SUCCESS;
00376 }
00377 
00379 ErrorCode VarLenSparseTag::num_tagged_entities( const SequenceManager*,
00380                                                 size_t& output_count,
00381                                                 EntityType type,
00382                                                 const Range* intersect ) const
00383 {
00384   InsertCount counter( output_count );
00385   get_tagged( mData, counter, type, intersect );
00386   output_count = counter.end();
00387   return MB_SUCCESS;
00388 }
00389 
00390 ErrorCode VarLenSparseTag::find_entities_with_value( 
00391                               const SequenceManager* seqman,
00392                               Error*,
00393                               Range& output_entities,
00394                               const void* value,
00395                               int value_bytes,
00396                               const EntityType type,
00397                               const Range* intersect_entities ) const
00398 {
00399   if (value_bytes && value_bytes != get_size())
00400     return MB_INVALID_SIZE;
00401   
00402   MapType::const_iterator iter, end;
00403 #ifdef HAVE_UNORDERED_MAP
00404   if (intersect_entities) {
00405     std::pair<Range::iterator,Range::iterator> r;
00406     if (type == MBMAXTYPE) {
00407       r.first = intersect_entities->begin();
00408       r.second = intersect_entities->end();
00409     }
00410     else {
00411       r = intersect_entities->equal_range( type );
00412     }
00413     
00414     
00415     find_map_varlen_values_equal( *this, value, get_size(), 
00416                                   r.first, r.second,
00417                                   mData, output_entities );
00418   }
00419   else if (type == MBMAXTYPE) {
00420     find_tag_varlen_values_equal( *this, value, get_size(), 
00421                                   mData.begin(), mData.end(), 
00422                                   output_entities );
00423   }
00424   else {
00425     Range tmp;
00426     seqman->get_entities( type, tmp );
00427     find_map_varlen_values_equal( *this, value, get_size(), 
00428                                   tmp.begin(), tmp.end(),
00429                                   mData, output_entities );
00430   }
00431 #else
00432   if (intersect_entities) {
00433     for (Range::const_pair_iterator p = intersect_entities->begin();
00434          p != intersect_entities->end(); ++p) {
00435       iter = mData.lower_bound( p->first );
00436       end = mData.upper_bound( p->second );
00437       find_tag_varlen_values_equal( *this, value, get_size(), iter, end, 
00438                                     output_entities);
00439     }
00440   }
00441   else {
00442     if (type == MBMAXTYPE) {
00443       iter = mData.begin();
00444       end = mData.end();
00445     }
00446     else {
00447       iter = mData.lower_bound( CREATE_HANDLE( type, MB_START_ID ) );
00448       end = mData.upper_bound( CREATE_HANDLE( type, MB_END_ID ) );
00449     }
00450     find_tag_varlen_values_equal( *this, value, get_size(), iter, end, 
00451                                   output_entities);
00452   }
00453 #endif
00454   
00455   return MB_SUCCESS;
00456 }
00457 
00458 bool VarLenSparseTag::is_tagged( const SequenceManager*, EntityHandle h ) const
00459 {
00460   return mData.find(h) != mData.end();
00461 }
00462   
00463 ErrorCode VarLenSparseTag::get_memory_use( const SequenceManager*,
00464                                            unsigned long& total,
00465                                            unsigned long& per_entity ) const
00466 
00467 {
00468   total = mData.size() * (3*sizeof(void*) + sizeof(VarLenTag));
00469   for (MapType::const_iterator i = mData.begin(); i != mData.end(); ++i)
00470     total += i->second.mem();
00471   if (mData.size())
00472     per_entity = total / mData.size();
00473   total += sizeof(*this) + TagInfo::get_memory_use();
00474       
00475   return MB_SUCCESS;
00476 }
00477 
00478 } // namespace moab
00479 
00480 
00481 
00482 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines