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