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