MOAB: Mesh Oriented datABase  (version 5.2.1)
SparseTag.hpp
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 #ifndef SPARSE_TAG_HPP
00017 #define SPARSE_TAG_HPP
00018 
00019 #ifndef IS_BUILDING_MB
00020 #error "SparseTag.hpp isn't supposed to be included into an application"
00021 #endif
00022 
00023 #ifdef WIN32
00024 #pragma warning( disable : 4786 )
00025 #endif
00026 
00027 #include "moab/MOABConfig.h"
00028 #define STRINGIFY_( X ) #X
00029 #define STRINGIFY( X )  STRINGIFY_( X )
00030 #ifdef MOAB_HAVE_UNORDERED_MAP
00031 #include STRINGIFY( MOAB_HAVE_UNORDERED_MAP )
00032 #else
00033 #include <map>
00034 #endif
00035 #include <vector>
00036 
00037 #include "TagInfo.hpp"
00038 #include <stdlib.h>
00039 
00040 namespace moab
00041 {
00042 
00043 //! allocator for tag data
00044 class SparseTagDataAllocator
00045 {
00046   public:
00047     //! constructor
00048     SparseTagDataAllocator() {}
00049     //! destructor
00050     ~SparseTagDataAllocator() {}
00051     //! allocates memory of size and returns pointer
00052     void* allocate( size_t data_size )
00053     {
00054         return malloc( data_size );
00055     }
00056     //! frees the memory
00057     void destroy( void* p )
00058     {
00059         free( p );
00060     }
00061 };
00062 
00063 //! Sparse tag data
00064 class SparseTag : public TagInfo
00065 {
00066   public:
00067     SparseTag( const char* name, int size, DataType type, const void* default_value );
00068 
00069     ~SparseTag();
00070 
00071     virtual TagType get_storage_type() const;
00072 
00073     /**\brief Remove/clear tag data for all entities
00074      *
00075      * Remove tag values from entities.
00076      *
00077      *\param delete_pending  If true, then release any global
00078      *          data associated with the tag in preparation for deleting
00079      *          the tag itself.
00080      *
00081      *\Note Invalidates tag if \c tag_delete_pending is true.  The only
00082      *        valid method that can be invoked that is is the destructor.
00083      *
00084      *\param seqman    Pointer to mesh entity database
00085      */
00086     virtual ErrorCode release_all_data( SequenceManager* seqman, Error* error_handler, bool delete_pending );
00087 
00088     /**\brief Get tag value for passed entities
00089      *
00090      * Get tag values for specified entities.
00091      *
00092      *\Note Will fail for variable-length data.
00093      *\param seqman Pointer to mesh entity database
00094      *\param entities Entity handles for which to retrieve tag data
00095      *\param num_entities Length of \c entities array
00096      *\param data Pointer to memory in which to store consecutive tag values,
00097      *            one for each passed entity.
00098      */
00099     virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
00100                                 size_t num_entities, void* data ) const;
00101 
00102     /**\brief Get tag value for passed entities
00103      *
00104      * Get tag values for specified entities.
00105      *
00106      *\Note Will fail for variable-length data.
00107      *\param seqman Pointer to mesh entity database
00108      *\param entities Entity handles for which to retrieve tag data
00109      *\param data Pointer to memory in which to store consecutive tag values,
00110      *            one for each passed entity.
00111      */
00112     virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const Range& entities,
00113                                 void* data ) const;
00114 
00115     /**\brief Get tag value for passed entities
00116      *
00117      * Get tag values for specified entities.
00118      *
00119      *\param seqman    Pointer to mesh entity database
00120      *\param entities  Entity handles for which to retrieve tag data
00121      *\param num_entities Length of \c entities array
00122      *\param data_ptrs Array of pointers to tag values, one pointer
00123      *                 for each passed entity.
00124      *\param data_lengths One value for each entity specifying the
00125      *                length of the tag value for the corresponding
00126      *                entity.
00127      */
00128     virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
00129                                 size_t num_entities, const void** data_ptrs, int* data_lengths ) const;
00130 
00131     /**\brief Get tag value for passed entities
00132      *
00133      * Get tag values for specified entities.
00134      *
00135      *\param seqman    Pointer to mesh entity database
00136      *\param entities  Entity handles for which to retrieve tag data
00137      *\param data_ptrs Array of pointers to tag values, one pointer
00138      *                 for each passed entity.
00139      *\param data_lengths One value for each entity specifying the
00140      *                length of the tag value for the corresponding
00141      *                entity.
00142      */
00143     virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const Range& entities,
00144                                 const void** data_ptrs, int* data_lengths ) const;
00145 
00146     /**\brief Set tag value for passed entities
00147      *
00148      * Store tag data or update stored tag values
00149      *\Note Will fail for variable-length data.
00150      *\param seqman Pointer to mesh entity database
00151      *\param entities Entity handles for which to store tag data
00152      *\param num_entities Length of \c entities array
00153      *\param data Pointer to memory holding consecutive tag values,
00154      *            one for each passed entity.
00155      */
00156     virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
00157                                 size_t num_entities, const void* data );
00158 
00159     /**\brief Set tag value for passed entities
00160      *
00161      * Store tag data or update stored tag values
00162      *\Note Will fail for variable-length data.
00163      *\param seqman Pointer to mesh entity database
00164      *\param entities Entity handles for which to store tag data
00165      *\param data Pointer to memory holding consecutive tag values,
00166      *            one for each passed entity.
00167      */
00168     virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const Range& entities,
00169                                 const void* data );
00170 
00171     /**\brief Set tag value for passed entities
00172      *
00173      * Store tag data or update stored tag values
00174      *
00175      *\param seqman    Pointer to mesh entity database
00176      *\param entities  Entity handles for which to store tag data
00177      *\param num_entities Length of \c entities array
00178      *\param data_ptrs Array of pointers to tag values, one pointer
00179      *                 for each passed entity.
00180      *\param data_lengths One value for each entity specifying the
00181      *                length of the tag value for the corresponding
00182      *                entity.  Array is required for variable-length
00183      *                tags and is ignored for fixed-length tags.
00184      */
00185     virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
00186                                 size_t num_entities, void const* const* data_ptrs, const int* data_lengths );
00187 
00188     /**\brief Set tag value for passed entities
00189      *
00190      * Store tag data or update stored tag values
00191      *
00192      *\param seqman    Pointer to mesh entity database
00193      *\param entities  Entity handles for which to store tag data
00194      *\param data_ptrs Array of pointers to tag values, one pointer
00195      *                 for each passed entity.
00196      *\param data_lengths One value for each entity specifying the
00197      *                length of the tag value for the corresponding
00198      *                entity.  Array is required for variable-length
00199      *                tags and is ignored for fixed-length tags.
00200      */
00201     virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const Range& entities,
00202                                 void const* const* data_ptrs, const int* data_lengths );
00203 
00204     /**\brief Set tag value for passed entities
00205      *
00206      * Store tag data or update stored tag values.
00207      *
00208      *\param seqman    Pointer to mesh entity database
00209      *\param entities  Entity handles for which to store tag data
00210      *\param num_entities Length of \c entities array
00211      *\param value_ptr Pointer to a single tag value which is to be
00212      *                 stored for each of the passed entities.
00213      *\param value_len Length of tag value in bytes.  Ignored for
00214      *                 fixed-length tags.  Required for variable-
00215      *                 length tags.
00216      */
00217     virtual ErrorCode clear_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
00218                                   size_t num_entities, const void* value_ptr, int value_len = 0 );
00219 
00220     /**\brief Set tag value for passed entities
00221      *
00222      * Store tag data or update stored tag values.
00223      *
00224      *\param seqman    Pointer to mesh entity database
00225      *\param entities  Entity handles for which to store tag data
00226      *\param value_ptr Pointer to a single tag value which is to be
00227      *                 stored for each of the passed entities.
00228      *\param value_len Length of tag value in bytes.  Ignored for
00229      *                 fixed-length tags.  Required for variable-
00230      *                 length tags.
00231      */
00232     virtual ErrorCode clear_data( SequenceManager* seqman, Error* error_handler, const Range& entities,
00233                                   const void* value_ptr, int value_len = 0 );
00234 
00235     /**\brief Remove/clear tag data for entities
00236      *
00237      * Remove tag values from entities.
00238      *
00239      *\param seqman    Pointer to mesh entity database
00240      *\param entities  Entity handles for which to store tag data
00241      *\param num_entities Length of \c entities array
00242      */
00243     virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
00244                                    size_t num_entities );
00245 
00246     /**\brief Remove/clear tag data for entities
00247      *
00248      * Remove tag values from entities.
00249      *
00250      *\param seqman    Pointer to mesh entity database
00251      *\param entities  Entity handles for which to store tag data
00252      */
00253     virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const Range& entities );
00254 
00255     /**\brief Access tag data via direct pointer into contiguous blocks
00256      *
00257      * Iteratively obtain direct access to contiguous blocks of tag
00258      * storage.  This function cannot be used with bit tags because
00259      * of the compressed bit storage.  This function cannot be used
00260      * with variable length tags because it does not provide a mechanism
00261      * to determine the length of the value for each entity.  This
00262      * function may be used with sparse tags, but if it is used, it
00263      * will return data for a single entity at a time.
00264      *
00265      *\param iter        As input, the first entity for which to return
00266      *                   data.  As output, one past the last entity for
00267      *                   which data was returned.
00268      *\param end         One past the last entity for which data is desired
00269      *\param data_ptr    Output: pointer to tag storage.
00270      *\param allocate    If true, space for this tag will be allocated, if not it wont
00271      *
00272      *\Note If this function is called for entities for which no tag value
00273      *      has been set, but for which a default value exists, it will
00274      *      force the allocation of explicit storage for each such entity
00275      *      even though MOAB would normally not explicitly store tag values
00276      *      for such entities.
00277      */
00278     virtual ErrorCode tag_iterate( SequenceManager* seqman, Error* error_handler, Range::iterator& iter,
00279                                    const Range::iterator& end, void*& data_ptr, bool allocate = true );
00280 
00281     /**\brief Get all tagged entities
00282      *
00283      * Get the list of entities for which the a tag value has been set,
00284      * or a close approximation if the tag storage scheme cannot
00285      * accurately determine exactly which entities have explicit values.
00286      *
00287      *\param seqman   Pointer to entity storage database
00288      *\param output_entities Results *appended* to this range
00289      *\param type     Optional entity type.  If specified, search is
00290      *                limited to entities of specified type.
00291      *\param intersect Optional intersect list.  If specified,
00292      *                search is restricted to entities in this list.
00293      */
00294     virtual ErrorCode get_tagged_entities( const SequenceManager* seqman, Range& output_entities,
00295                                            EntityType type = MBMAXTYPE, const Range* intersect = 0 ) const;
00296 
00297     /**\brief Count all tagged entities
00298      *
00299      * Count the entities for which the a tag value has been set,
00300      * or a close approximation if the tag storage scheme cannot
00301      * accurately determine exactly which entities have explicit values.
00302      *
00303      *\param seqman   Pointer to entity storage database
00304      *\param output_count This is *incremented* for each detected entity.
00305      *\param type     Optional entity type.  If specified, search is
00306      *                limited to entities of specified type.
00307      *\param intersect Optional intersect list.  If specified,
00308      *                search is restricted to entities in this list.
00309      */
00310     virtual ErrorCode num_tagged_entities( const SequenceManager* seqman, size_t& output_count,
00311                                            EntityType type = MBMAXTYPE, const Range* intersect = 0 ) const;
00312 
00313     /**\brief Get all tagged entities with tag value
00314      *
00315      * Get the list of entities which have the specified tag value.
00316      *
00317      *\param seqman   Pointer to entity storage database
00318      *\param output_entities Results *appended* to this range
00319      *\param value    Pointer to tag value
00320      *\param value_bytes Size of tag value in bytes.
00321      *\param type     Optional entity type.  If specified, search is
00322      *                limited to entities of specified type.
00323      *\param intersect_entities Optional intersect list.  If specified,
00324      *                search is restricted to entities in this list.
00325      */
00326     virtual ErrorCode find_entities_with_value( const SequenceManager* seqman, Error* error_handler,
00327                                                 Range& output_entities, const void* value, int value_bytes = 0,
00328                                                 EntityType type                 = MBMAXTYPE,
00329                                                 const Range* intersect_entities = 0 ) const;
00330 
00331     /**\brief Check if entity is tagged */
00332     virtual bool is_tagged( const SequenceManager*, EntityHandle h ) const;
00333 
00334     /**\brief Get memory use for tag data.
00335      *
00336      */
00337     virtual ErrorCode get_memory_use( const SequenceManager* seqman, unsigned long& total,
00338                                       unsigned long& per_entity ) const;
00339 
00340     //! get number of entities
00341     unsigned long get_number_entities()
00342     {
00343         return mData.size();
00344     }
00345 
00346     //! map of entity id and tag data
00347 #ifdef MOAB_HAVE_UNORDERED_MAP
00348     typedef MOAB_UNORDERED_MAP_NS::unordered_map< EntityHandle, void* > MapType;
00349 #else
00350     typedef std::map< EntityHandle, void* > MapType;
00351 #endif
00352 
00353   private:
00354     SparseTag( const SparseTag& );
00355     SparseTag& operator=( const SparseTag& );
00356 
00357     //! allocate an entry for this sparse tag w/o setting its value (yet)
00358     inline void* allocate_data( EntityHandle h, MapType::const_iterator iter, bool copy_default = true );
00359 
00360     //! set the tag data for an entity id
00361     //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for
00362     //!      variable-length tag.
00363     inline ErrorCode set_data( Error*, EntityHandle entity_handle, const void* data );
00364 
00365     //! get the tag data for an entity id
00366     //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for
00367     //!      variable-length tag.
00368     inline ErrorCode get_data( Error*, EntityHandle entity_handle, void* data ) const;
00369 
00370     //! get the variable-length data for an entity id
00371     inline ErrorCode get_data_ptr( EntityHandle entity_handle, const void*& data, bool allocate = true ) const;
00372 
00373     //! removes the data
00374     inline ErrorCode remove_data( Error*, EntityHandle entity_handle );
00375 
00376     //! allocator for this collection
00377     SparseTagDataAllocator mAllocator;
00378 
00379     MapType mData;
00380 };
00381 
00382 inline void* SparseTag::allocate_data( EntityHandle h,
00383 #ifdef MOAB_HAVE_UNORDERED_MAP
00384                                        MapType::const_iterator iter,
00385 #else
00386                                        MapType::const_iterator,
00387 #endif
00388                                        bool copy_default )
00389 {
00390     void* new_data = mAllocator.allocate( get_size() );
00391 #ifdef MOAB_HAVE_UNORDERED_MAP
00392     mData.insert( iter, std::pair< const EntityHandle, void* >( h, new_data ) );
00393 #else
00394     mData[h] = new_data;
00395 #endif
00396     if( copy_default ) memcpy( new_data, get_default_value(), get_size() );
00397     return new_data;
00398 }
00399 
00400 }  // namespace moab
00401 
00402 #endif  // SPARSE_TAG_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines