moab
SparseTagSuperCollection.cpp
Go to the documentation of this file.
00001 
00017 /**********************************************
00018  * Filename   :     SparseTagSuperCollection.cpp
00019  *
00020  * Purpose    :     To store any size data with
00021  *                  any entity handle
00022  *
00023  * Creator    :     Clinton Stimpson
00024  *
00025  * Date       :     3 April 2002
00026  *
00027  * ********************************************/
00028 
00029 
00030 #include <memory.h>
00031 #include <algorithm>
00032 
00033 #include "SparseTagSuperCollection.hpp"
00034 #include "SparseTagCollection.hpp"
00035 #include "moab/Range.hpp"
00036 
00037 namespace moab {
00038 
00039 /*
00040   SparseTagSuperCollection functions -----------------------------
00041 */
00042 
00043 SparseTagSuperCollection::~SparseTagSuperCollection()
00044 {
00045   std::vector<SparseTagCollection*>::iterator tag_iterator;
00046   for(tag_iterator = mDataTags.begin(); tag_iterator != mDataTags.end(); ++tag_iterator)
00047     delete *tag_iterator;
00048   mDataTags.clear();
00049 }
00050 
00051 void SparseTagSuperCollection::reset_data()
00052 {
00053   std::vector<SparseTagCollection*>::iterator tag_iterator;
00054   for(tag_iterator = mDataTags.begin(); tag_iterator != mDataTags.end(); ++tag_iterator)
00055   {
00056     if (*tag_iterator) {
00057       int data_size = (*tag_iterator)->tag_size();
00058       delete *tag_iterator;
00059       *tag_iterator = new SparseTagCollection(data_size);
00060     }
00061   }
00062   
00063 }
00064 
00065 ErrorCode SparseTagSuperCollection::reserve_tag_id(int data_size, TagId tag_id)
00066 {
00067   if(data_size<=0 && data_size != MB_VARIABLE_LENGTH)
00068     return MB_FAILURE;
00069 
00070   if (tag_id >= mDataTags.size())
00071     mDataTags.resize( tag_id+1, 0 );
00072     
00073   if (mDataTags[tag_id])
00074     return MB_FAILURE;
00075     
00076   mDataTags[tag_id] = new SparseTagCollection(data_size);
00077   return MB_SUCCESS;
00078 }
00079 
00080 ErrorCode SparseTagSuperCollection::release_tag_id(TagId tag_id)
00081 {
00082   if (tag_id >= mDataTags.size() || !mDataTags[tag_id])
00083     return MB_TAG_NOT_FOUND;
00084   
00085   delete mDataTags[tag_id];
00086   mDataTags[tag_id] = 0;
00087   return MB_SUCCESS;
00088 }
00089 
00090 int SparseTagSuperCollection::tag_size(const TagId tag_id) const
00091 {
00092   SparseTagCollection* coll = get_collection(tag_id);
00093   return coll ? coll->tag_size() : 0;
00094 }
00095 
00096 
00097 ErrorCode SparseTagSuperCollection::set_data( TagId tag_handle,
00098                                                 const EntityHandle* handles,
00099                                                 int num_handles,
00100                                                 const void* data )
00101 {
00102   SparseTagCollection* coll = get_collection(tag_handle);
00103   if (!coll)
00104     return MB_TAG_NOT_FOUND;
00105     
00106   const int length = coll->tag_size();
00107   if (length == MB_VARIABLE_LENGTH)
00108     return MB_VARIABLE_DATA_LENGTH;
00109 
00110   ErrorCode rval, result = MB_SUCCESS;
00111   const unsigned char* ptr = reinterpret_cast<const unsigned char*>(data);
00112   const EntityHandle *const end = handles + num_handles;
00113   for (const EntityHandle* i = handles; i != end; ++i, ptr += length) {
00114     rval = coll->set_data( *i, ptr );
00115     if (MB_SUCCESS != rval)
00116       result = rval;
00117   }
00118     
00119   return result;
00120 }
00121 
00122 ErrorCode SparseTagSuperCollection::set_data( TagId tag_handle,
00123                                               const EntityHandle* handles,
00124                                               int num_handles,
00125                                               void const* const* data_ptrs,
00126                                               const int* lengths,
00127                                               bool one_value )
00128 {
00129   SparseTagCollection* coll = get_collection(tag_handle);
00130   if (!coll)
00131     return MB_TAG_NOT_FOUND;
00132   
00133   const bool step = !one_value;
00134   const int length = coll->tag_size();
00135   int length_step;
00136   if (length == MB_VARIABLE_LENGTH) {
00137     if (!lengths)
00138       return MB_VARIABLE_DATA_LENGTH;
00139     length_step = step;
00140   }
00141   else {
00142     lengths = &length;
00143     length_step = 0;
00144   }
00145 
00146   ErrorCode rval, result = MB_SUCCESS;
00147   const EntityHandle *const end = handles + num_handles;
00148   void const* const* ptr = data_ptrs;
00149   for (const EntityHandle* i = handles; i != end; ++i, ptr += step, lengths += length_step) {
00150     rval = coll->set_data( *i, *ptr, *lengths );
00151     if (MB_SUCCESS != rval)
00152       result = rval;
00153   }
00154     
00155   return result;
00156 }
00157 
00158 
00159 ErrorCode SparseTagSuperCollection::set_data( TagId tag_handle,
00160                                                 const Range& handles,
00161                                                 const void* data )
00162 {
00163   SparseTagCollection* coll = get_collection(tag_handle);
00164   if (!coll)
00165     return MB_TAG_NOT_FOUND;
00166     
00167   const int length = coll->tag_size();
00168   if (length == MB_VARIABLE_LENGTH)
00169     return MB_VARIABLE_DATA_LENGTH;
00170 
00171   ErrorCode rval, result = MB_SUCCESS;
00172   const unsigned char* ptr = reinterpret_cast<const unsigned char*>(data);
00173   for (Range::const_iterator i = handles.begin(); i != handles.end(); ++i, ptr += length) {
00174     rval = coll->set_data( *i, ptr );
00175     if (MB_SUCCESS != rval)
00176       result = rval;
00177   }
00178     
00179   return result;
00180 }
00181 
00182 ErrorCode SparseTagSuperCollection::set_data( TagId tag_handle,
00183                                               const Range& handles,
00184                                               void const* const* data_ptrs,
00185                                               const int* lengths,
00186                                               bool one_value )
00187 {
00188   SparseTagCollection* coll = get_collection(tag_handle);
00189   if (!coll)
00190     return MB_TAG_NOT_FOUND;
00191   
00192   const bool step = !one_value;
00193   const int length = coll->tag_size();
00194   int length_step;
00195   if (length == MB_VARIABLE_LENGTH) {
00196     if (!lengths)
00197       return MB_VARIABLE_DATA_LENGTH;
00198     length_step = step;
00199   }
00200   else {
00201     lengths = &length;
00202     length_step = 0;
00203   }
00204 
00205   ErrorCode rval, result = MB_SUCCESS;
00206   void const* const* ptr = data_ptrs;
00207   for (Range::const_iterator i = handles.begin(); i != handles.end(); ++i, ptr += step, lengths += length_step) {
00208     rval = coll->set_data( *i, *ptr, *lengths );
00209     if (MB_SUCCESS != rval)
00210       result = rval;
00211   }
00212     
00213   return result;
00214 }
00215 
00216 ErrorCode SparseTagSuperCollection::tag_iterate( TagId tag_handle,
00217                                               Range::iterator& iter,
00218                                               const Range::iterator& end,
00219                                               void*& data_ptr_out,
00220                                               const void* default_value )
00221 
00222 {
00223     // Note: We are asked to returning a block of contiguous storage
00224     //       for some block of contiguous handles for which the tag 
00225     //       storage is also contiguous.  As sparse tag storage is
00226     //       never contigous, all we can do is return a pointer to the
00227     //       data for the first entity.
00228 
00229     // If asked for nothing, successfully return nothing.
00230   if (iter == end)
00231     return MB_SUCCESS;
00232 
00233   SparseTagCollection* coll = get_collection(tag_handle);
00234   if (!coll)
00235     return MB_TAG_NOT_FOUND;
00236     
00237     // not supported for variable-length tags
00238   const int length = coll->tag_size();
00239   if (length == MB_VARIABLE_LENGTH)
00240     return MB_VARIABLE_DATA_LENGTH;
00241 
00242     // get pointer to tag storage for entity pointed to by iter
00243   int junk;
00244   ErrorCode rval = coll->get_data( *iter, data_ptr_out, junk );
00245   if (MB_SUCCESS != rval) {
00246       // if no tag value but default_value, then set tag to
00247       // default_value and return the new tag storage.  Note:
00248       // it is not sufficient to return the passed default_value
00249       // pointer because we are returning an non-const pointer that
00250       // could be modified by the caller.
00251     if (MB_TAG_NOT_FOUND == rval && default_value) {
00252       rval = coll->set_data( *iter, default_value );
00253       if (MB_SUCCESS != rval)
00254         return rval;
00255       rval = coll->get_data( *iter, data_ptr_out, junk );
00256       if (MB_SUCCESS != rval)
00257         return rval;
00258     }
00259     else {
00260       return rval;
00261     }
00262   }
00263     
00264     // increment iterator and return
00265   ++iter;
00266   return MB_SUCCESS;
00267 }
00268 
00269 ErrorCode SparseTagSuperCollection::get_data( TagId tag_handle,
00270                                                 const EntityHandle* handles,
00271                                                 int num_handles,
00272                                                 void* data,
00273                                                 const void* default_value ) const
00274 {
00275   SparseTagCollection* coll = get_collection(tag_handle);
00276   if (!coll)
00277     return MB_TAG_NOT_FOUND;
00278     
00279   const int length = coll->tag_size();
00280   if (length == MB_VARIABLE_LENGTH)
00281     return MB_VARIABLE_DATA_LENGTH;
00282 
00283   ErrorCode rval;
00284   unsigned char* ptr = reinterpret_cast<unsigned char*>(data);
00285   const EntityHandle *const end = handles + num_handles;
00286   for (const EntityHandle* i = handles; i != end; ++i, ptr += length) {
00287     rval = coll->get_data( *i, ptr );
00288     if (MB_SUCCESS != rval) {
00289       if (MB_TAG_NOT_FOUND == rval && default_value) 
00290         memcpy( ptr, default_value, length );
00291       else
00292         return rval;
00293     }
00294   }
00295     
00296   return MB_SUCCESS;
00297 }
00298 
00299 ErrorCode SparseTagSuperCollection::get_data( TagId tag_handle,
00300                                                 const EntityHandle* handles,
00301                                                 int num_handles,
00302                                                 const void** data,
00303                                                 int* lengths,
00304                                                 const void* default_value,
00305                                                 int default_val_length ) const
00306 {
00307   SparseTagCollection* coll = get_collection(tag_handle);
00308   if (!coll)
00309     return MB_TAG_NOT_FOUND;
00310   
00311   int junk_length;
00312   int length_step = 1;
00313   const int length = coll->tag_size();
00314   if (!lengths) {
00315     if (length == MB_VARIABLE_LENGTH)
00316       return MB_VARIABLE_DATA_LENGTH;
00317     lengths = &junk_length;
00318     length_step = 0;
00319   }
00320   
00321   
00322   ErrorCode rval, result = MB_SUCCESS;
00323   const EntityHandle *const end = handles + num_handles;
00324   for (const EntityHandle* i = handles; i != end; ++i, ++data, lengths += length_step) {
00325     void* ptr;
00326     rval = coll->get_data( *i, ptr, *lengths );
00327     if (MB_SUCCESS == rval)
00328       *data = ptr;
00329     else if (MB_TAG_NOT_FOUND == rval && default_value) {
00330       *data = default_value;
00331       *lengths = default_val_length;
00332     }
00333     else {
00334       *data = 0;
00335       *lengths = 0;
00336       result = rval;
00337     }
00338   }
00339     
00340   return result;
00341 }
00342 
00343 
00344 ErrorCode SparseTagSuperCollection::get_data( TagId tag_handle,
00345                                                 const Range& handles,
00346                                                 void* data,
00347                                                 const void* default_value ) const
00348 {
00349   SparseTagCollection* coll = get_collection(tag_handle);
00350   if (!coll)
00351     return MB_TAG_NOT_FOUND;
00352     
00353   const int length = coll->tag_size();
00354   if (length == MB_VARIABLE_LENGTH)
00355     return MB_VARIABLE_DATA_LENGTH;
00356 
00357   ErrorCode rval;
00358   unsigned char* ptr = reinterpret_cast<unsigned char*>(data);
00359   for (Range::const_iterator i = handles.begin(); i != handles.end(); ++i, ptr += length) {
00360     rval = coll->get_data( *i, ptr );
00361     if (MB_SUCCESS != rval) {
00362       if (MB_TAG_NOT_FOUND == rval && default_value) 
00363         memcpy( ptr, default_value, length );
00364       else
00365         return rval;
00366     }
00367   }
00368     
00369   return MB_SUCCESS;
00370 }
00371 
00372 ErrorCode SparseTagSuperCollection::get_data( TagId tag_handle,
00373                                                 const Range& handles,
00374                                                 const void** data,
00375                                                 int* lengths,
00376                                                 const void* default_value,
00377                                                 int default_val_length ) const
00378 {
00379   SparseTagCollection* coll = get_collection(tag_handle);
00380   if (!coll)
00381     return MB_TAG_NOT_FOUND;
00382   
00383   int junk_length;
00384   int length_step = 1;
00385   const int length = coll->tag_size();
00386   if (!lengths) {
00387     if (length == MB_VARIABLE_LENGTH)
00388       return MB_VARIABLE_DATA_LENGTH;
00389     lengths = &junk_length;
00390     length_step = 0;
00391   }
00392   
00393   
00394   ErrorCode rval, result = MB_SUCCESS;
00395   for (Range::const_iterator i = handles.begin(); i != handles.end(); ++i, ++data, lengths += length_step) {
00396     void* ptr;
00397     rval = coll->get_data( *i, ptr, *lengths );
00398     if (MB_SUCCESS == rval) {
00399       *data = ptr;
00400     }
00401     else if (MB_TAG_NOT_FOUND == rval && default_value) {
00402       *data = default_value;
00403       *lengths = default_val_length;
00404     }
00405     else {
00406       *data = 0;
00407       *lengths = 0;
00408       result = rval;
00409     }
00410   }
00411     
00412   return result;
00413 }
00414 
00415 ErrorCode SparseTagSuperCollection::remove_data( const TagId tag_handle, 
00416     const EntityHandle entity_handle )
00417 {
00418   SparseTagCollection* coll = get_collection(tag_handle);
00419   return coll ? coll->remove_data( entity_handle ) : MB_TAG_NOT_FOUND;
00420 }
00421 
00422 
00424 ErrorCode SparseTagSuperCollection::get_entities(const TagId tag_handle, 
00425                                                    Range &entities)
00426 {
00427   SparseTagCollection* coll = get_collection(tag_handle);
00428   return coll ? coll->get_entities(entities) : MB_TAG_NOT_FOUND;
00429 }
00430 
00432 ErrorCode SparseTagSuperCollection::get_entities(const TagId tag_handle, const EntityType type,
00433                                                     Range &entities)
00434 {
00435   SparseTagCollection* coll = get_collection(tag_handle);
00436   return coll ? coll->get_entities(type, entities) : MB_TAG_NOT_FOUND;
00437 }
00438 
00440 ErrorCode SparseTagSuperCollection::get_entities(const Range &range,
00441                                                     const TagId tag_handle, const EntityType type,
00442                                                     Range &entities)
00443 {
00444   SparseTagCollection* coll = get_collection(tag_handle);
00445   if (!coll)
00446     return MB_TAG_NOT_FOUND;
00447   
00448   Range dum_range;
00449   ErrorCode result = coll->get_entities(type, dum_range);
00450 
00451   std::set_intersection(dum_range.begin(), dum_range.end(),
00452                         range.begin(), range.end(),
00453                         range_inserter(entities));
00454   
00455   return result;
00456 }
00457 
00458 ErrorCode SparseTagSuperCollection::get_tags(const EntityHandle entity,
00459                                                 std::vector<Tag> &all_tags)
00460 {
00461   for (TagId id = 0; id < mDataTags.size(); ++id)
00462     if (mDataTags[id] && mDataTags[id]->contains(entity))
00463       all_tags.push_back( TAG_HANDLE_FROM_ID( id, MB_TAG_SPARSE ) );
00464   
00465   return MB_SUCCESS;
00466 }
00467 
00469 ErrorCode SparseTagSuperCollection::get_entities_with_tag_value(
00470                            const TagId tag_handle, 
00471                            const TagInfo& tag_info,
00472                            const EntityType type,
00473                            Range &entities, 
00474                            const void* tag_value,
00475                            int value_size)
00476 {
00477   SparseTagCollection* coll = get_collection(tag_handle);
00478   if (!coll)
00479     return MB_TAG_NOT_FOUND;
00480   
00481   return coll->get_entities_with_tag_value(tag_info, type, entities, tag_value, value_size);
00482 }
00483 
00485 ErrorCode SparseTagSuperCollection::get_entities_with_tag_value(
00486                           const Range &range,
00487                           const TagId tag_handle, 
00488                           const TagInfo& tag_info,
00489                           const EntityType type,
00490                           Range &entities, 
00491                           const void* tag_value,
00492                           int value_size)
00493 {
00494   SparseTagCollection* coll = get_collection(tag_handle);
00495   if (!coll)
00496     return MB_TAG_NOT_FOUND;
00497 
00498   Range dum_range;
00499   ErrorCode result = coll->get_entities_with_tag_value(
00500                            tag_info, type, dum_range, tag_value, value_size);
00501 
00502     // do this the hard way to preserve order in the vector
00503   std::set_intersection(range.begin(), range.end(),
00504                         dum_range.begin(), dum_range.end(),
00505                         range_inserter(entities));
00506   
00507   return result;
00508 }
00509 
00511 ErrorCode SparseTagSuperCollection::get_number_entities(const TagId tag_handle, const EntityType type,
00512                                                            int& num_entities)
00513 {
00514   SparseTagCollection* coll = get_collection(tag_handle);
00515   return coll ? coll->get_number_entities( type, num_entities ) : MB_TAG_NOT_FOUND;
00516 }
00517 
00519 ErrorCode SparseTagSuperCollection::get_number_entities(const Range &range,
00520                                                            const TagId tag_handle, const EntityType type,
00521                                                            int& num_entities)
00522 {
00523   Range dum_range;
00524   ErrorCode result = get_entities(range, tag_handle, type, dum_range);
00525   num_entities = dum_range.size();
00526   return result;
00527 }
00528 
00529 
00530 ErrorCode SparseTagSuperCollection::get_memory_use( TagId tag_id,
00531                                               unsigned long& total,
00532                                               unsigned long& per_entity )
00533 {
00534   SparseTagCollection* coll = get_collection(tag_id);
00535   if (!coll)
00536     return MB_TAG_NOT_FOUND;
00537 
00538     // 3*sizeof(void*)                      - std::map RB tree node
00539     // sizeof(void*)*sizeof(EntityHandle) - data in std::map node
00540     // coll->tag_size()                     - the actual tag data
00541   per_entity = 4*sizeof(void*)+sizeof(EntityHandle)+coll->tag_size();
00542     
00543     // Count number of occupied slots in mDataTags vector
00544   unsigned num_coll =0;
00545   for (unsigned i = 0; i < mDataTags.size(); ++i)
00546     if (mDataTags[i])
00547       ++num_coll;
00548 
00549     // amortized space in mDataTags vector
00550   total = sizeof(SparseTagCollection*) * mDataTags.capacity() / num_coll;
00551     // SparseTagCollection object for this tag
00552   total += sizeof(SparseTagCollection);
00553     // Per-entity data in SparseTagCollection
00554   total += per_entity * coll->get_number_entities();
00555   return MB_SUCCESS;
00556 }
00557 
00558 } // namespace moab
00559 
00560 
00561 
00562 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines