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