Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
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 <cstdlib>
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,
00100                                 Error* error_handler,
00101                                 const EntityHandle* entities,
00102                                 size_t num_entities,
00103                                 void* data ) const;
00104 
00105     /**\brief Get tag value for passed entities
00106      *
00107      * Get tag values for specified entities.
00108      *
00109      *\Note Will fail for variable-length data.
00110      *\param seqman Pointer to mesh entity database
00111      *\param entities Entity handles for which to retrieve tag data
00112      *\param data Pointer to memory in which to store consecutive tag values,
00113      *            one for each passed entity.
00114      */
00115     virtual ErrorCode get_data( const SequenceManager* seqman,
00116                                 Error* error_handler,
00117                                 const Range& entities,
00118                                 void* data ) const;
00119 
00120     /**\brief Get tag value for passed entities
00121      *
00122      * Get tag values for specified entities.
00123      *
00124      *\param seqman    Pointer to mesh entity database
00125      *\param entities  Entity handles for which to retrieve tag data
00126      *\param num_entities Length of \c entities array
00127      *\param data_ptrs Array of pointers to tag values, one pointer
00128      *                 for each passed entity.
00129      *\param data_lengths One value for each entity specifying the
00130      *                length of the tag value for the corresponding
00131      *                entity.
00132      */
00133     virtual ErrorCode get_data( const SequenceManager* seqman,
00134                                 Error* error_handler,
00135                                 const EntityHandle* entities,
00136                                 size_t num_entities,
00137                                 const void** data_ptrs,
00138                                 int* data_lengths ) const;
00139 
00140     /**\brief Get tag value for passed entities
00141      *
00142      * Get tag values for specified entities.
00143      *
00144      *\param seqman    Pointer to mesh entity database
00145      *\param entities  Entity handles for which to retrieve tag data
00146      *\param data_ptrs Array of pointers to tag values, one pointer
00147      *                 for each passed entity.
00148      *\param data_lengths One value for each entity specifying the
00149      *                length of the tag value for the corresponding
00150      *                entity.
00151      */
00152     virtual ErrorCode get_data( const SequenceManager* seqman,
00153                                 Error* error_handler,
00154                                 const Range& entities,
00155                                 const void** data_ptrs,
00156                                 int* data_lengths ) const;
00157 
00158     /**\brief Set tag value for passed entities
00159      *
00160      * Store tag data or update stored tag values
00161      *\Note Will fail for variable-length data.
00162      *\param seqman Pointer to mesh entity database
00163      *\param entities Entity handles for which to store tag data
00164      *\param num_entities Length of \c entities array
00165      *\param data Pointer to memory holding consecutive tag values,
00166      *            one for each passed entity.
00167      */
00168     virtual ErrorCode set_data( SequenceManager* seqman,
00169                                 Error* error_handler,
00170                                 const EntityHandle* entities,
00171                                 size_t num_entities,
00172                                 const void* data );
00173 
00174     /**\brief Set tag value for passed entities
00175      *
00176      * Store tag data or update stored tag values
00177      *\Note Will fail for variable-length data.
00178      *\param seqman Pointer to mesh entity database
00179      *\param entities Entity handles for which to store tag data
00180      *\param data Pointer to memory holding consecutive tag values,
00181      *            one for each passed entity.
00182      */
00183     virtual ErrorCode set_data( SequenceManager* seqman,
00184                                 Error* error_handler,
00185                                 const Range& entities,
00186                                 const void* data );
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 num_entities Length of \c entities array
00195      *\param data_ptrs Array of pointers to tag values, one pointer
00196      *                 for each passed entity.
00197      *\param data_lengths One value for each entity specifying the
00198      *                length of the tag value for the corresponding
00199      *                entity.  Array is required for variable-length
00200      *                tags and is ignored for fixed-length tags.
00201      */
00202     virtual ErrorCode set_data( SequenceManager* seqman,
00203                                 Error* error_handler,
00204                                 const EntityHandle* entities,
00205                                 size_t num_entities,
00206                                 void const* const* data_ptrs,
00207                                 const int* data_lengths );
00208 
00209     /**\brief Set tag value for passed entities
00210      *
00211      * Store tag data or update stored tag values
00212      *
00213      *\param seqman    Pointer to mesh entity database
00214      *\param entities  Entity handles for which to store tag data
00215      *\param data_ptrs Array of pointers to tag values, one pointer
00216      *                 for each passed entity.
00217      *\param data_lengths One value for each entity specifying the
00218      *                length of the tag value for the corresponding
00219      *                entity.  Array is required for variable-length
00220      *                tags and is ignored for fixed-length tags.
00221      */
00222     virtual ErrorCode set_data( SequenceManager* seqman,
00223                                 Error* error_handler,
00224                                 const Range& entities,
00225                                 void const* const* data_ptrs,
00226                                 const int* data_lengths );
00227 
00228     /**\brief Set tag value for passed entities
00229      *
00230      * Store tag data or update stored tag values.
00231      *
00232      *\param seqman    Pointer to mesh entity database
00233      *\param entities  Entity handles for which to store tag data
00234      *\param num_entities Length of \c entities array
00235      *\param value_ptr Pointer to a single tag value which is to be
00236      *                 stored for each of the passed entities.
00237      *\param value_len Length of tag value in bytes.  Ignored for
00238      *                 fixed-length tags.  Required for variable-
00239      *                 length tags.
00240      */
00241     virtual ErrorCode clear_data( SequenceManager* seqman,
00242                                   Error* error_handler,
00243                                   const EntityHandle* entities,
00244                                   size_t num_entities,
00245                                   const void* value_ptr,
00246                                   int value_len = 0 );
00247 
00248     /**\brief Set tag value for passed entities
00249      *
00250      * Store tag data or update stored tag values.
00251      *
00252      *\param seqman    Pointer to mesh entity database
00253      *\param entities  Entity handles for which to store tag data
00254      *\param value_ptr Pointer to a single tag value which is to be
00255      *                 stored for each of the passed entities.
00256      *\param value_len Length of tag value in bytes.  Ignored for
00257      *                 fixed-length tags.  Required for variable-
00258      *                 length tags.
00259      */
00260     virtual ErrorCode clear_data( SequenceManager* seqman,
00261                                   Error* error_handler,
00262                                   const Range& entities,
00263                                   const void* value_ptr,
00264                                   int value_len = 0 );
00265 
00266     /**\brief Remove/clear tag data for entities
00267      *
00268      * Remove tag values from entities.
00269      *
00270      *\param seqman    Pointer to mesh entity database
00271      *\param entities  Entity handles for which to store tag data
00272      *\param num_entities Length of \c entities array
00273      */
00274     virtual ErrorCode remove_data( SequenceManager* seqman,
00275                                    Error* error_handler,
00276                                    const EntityHandle* entities,
00277                                    size_t num_entities );
00278 
00279     /**\brief Remove/clear tag data for entities
00280      *
00281      * Remove tag values from entities.
00282      *
00283      *\param seqman    Pointer to mesh entity database
00284      *\param entities  Entity handles for which to store tag data
00285      */
00286     virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const Range& entities );
00287 
00288     /**\brief Access tag data via direct pointer into contiguous blocks
00289      *
00290      * Iteratively obtain direct access to contiguous blocks of tag
00291      * storage.  This function cannot be used with bit tags because
00292      * of the compressed bit storage.  This function cannot be used
00293      * with variable length tags because it does not provide a mechanism
00294      * to determine the length of the value for each entity.  This
00295      * function may be used with sparse tags, but if it is used, it
00296      * will return data for a single entity at a time.
00297      *
00298      *\param iter        As input, the first entity for which to return
00299      *                   data.  As output, one past the last entity for
00300      *                   which data was returned.
00301      *\param end         One past the last entity for which data is desired
00302      *\param data_ptr    Output: pointer to tag storage.
00303      *\param allocate    If true, space for this tag will be allocated, if not it wont
00304      *
00305      *\Note If this function is called for entities for which no tag value
00306      *      has been set, but for which a default value exists, it will
00307      *      force the allocation of explicit storage for each such entity
00308      *      even though MOAB would normally not explicitly store tag values
00309      *      for such entities.
00310      */
00311     virtual ErrorCode tag_iterate( SequenceManager* seqman,
00312                                    Error* error_handler,
00313                                    Range::iterator& iter,
00314                                    const Range::iterator& end,
00315                                    void*& data_ptr,
00316                                    bool allocate = true );
00317 
00318     /**\brief Get all tagged entities
00319      *
00320      * Get the list of entities for which the a tag value has been set,
00321      * or a close approximation if the tag storage scheme cannot
00322      * accurately determine exactly which entities have explicit values.
00323      *
00324      *\param seqman   Pointer to entity storage database
00325      *\param output_entities Results *appended* to this range
00326      *\param type     Optional entity type.  If specified, search is
00327      *                limited to entities of specified type.
00328      *\param intersect Optional intersect list.  If specified,
00329      *                search is restricted to entities in this list.
00330      */
00331     virtual ErrorCode get_tagged_entities( const SequenceManager* seqman,
00332                                            Range& output_entities,
00333                                            EntityType type        = MBMAXTYPE,
00334                                            const Range* intersect = 0 ) const;
00335 
00336     /**\brief Count all tagged entities
00337      *
00338      * Count the entities for which the a tag value has been set,
00339      * or a close approximation if the tag storage scheme cannot
00340      * accurately determine exactly which entities have explicit values.
00341      *
00342      *\param seqman   Pointer to entity storage database
00343      *\param output_count This is *incremented* for each detected entity.
00344      *\param type     Optional entity type.  If specified, search is
00345      *                limited to entities of specified type.
00346      *\param intersect Optional intersect list.  If specified,
00347      *                search is restricted to entities in this list.
00348      */
00349     virtual ErrorCode num_tagged_entities( const SequenceManager* seqman,
00350                                            size_t& output_count,
00351                                            EntityType type        = MBMAXTYPE,
00352                                            const Range* intersect = 0 ) const;
00353 
00354     /**\brief Get all tagged entities with tag value
00355      *
00356      * Get the list of entities which have the specified tag value.
00357      *
00358      *\param seqman   Pointer to entity storage database
00359      *\param output_entities Results *appended* to this range
00360      *\param value    Pointer to tag value
00361      *\param value_bytes Size of tag value in bytes.
00362      *\param type     Optional entity type.  If specified, search is
00363      *                limited to entities of specified type.
00364      *\param intersect_entities Optional intersect list.  If specified,
00365      *                search is restricted to entities in this list.
00366      */
00367     virtual ErrorCode find_entities_with_value( const SequenceManager* seqman,
00368                                                 Error* error_handler,
00369                                                 Range& output_entities,
00370                                                 const void* value,
00371                                                 int value_bytes                 = 0,
00372                                                 EntityType type                 = MBMAXTYPE,
00373                                                 const Range* intersect_entities = 0 ) const;
00374 
00375     /**\brief Check if entity is tagged */
00376     virtual bool is_tagged( const SequenceManager*, EntityHandle h ) const;
00377 
00378     /**\brief Get memory use for tag data.
00379      *
00380      */
00381     virtual ErrorCode get_memory_use( const SequenceManager* seqman,
00382                                       unsigned long& total,
00383                                       unsigned long& per_entity ) const;
00384 
00385     //! get number of entities
00386     unsigned long get_number_entities()
00387     {
00388         return mData.size();
00389     }
00390 
00391     //! map of entity id and tag data
00392 #ifdef MOAB_HAVE_UNORDERED_MAP
00393     typedef MOAB_UNORDERED_MAP_NS::unordered_map< EntityHandle, void* > MapType;
00394 #else
00395     typedef std::map< EntityHandle, void* > MapType;
00396 #endif
00397 
00398   private:
00399     SparseTag( const SparseTag& );
00400     SparseTag& operator=( const SparseTag& );
00401 
00402     //! allocate an entry for this sparse tag w/o setting its value (yet)
00403     inline void* allocate_data( EntityHandle h, MapType::const_iterator iter, bool copy_default = true );
00404 
00405     //! set the tag data for an entity id
00406     //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for
00407     //!      variable-length tag.
00408     inline ErrorCode set_data( Error*, EntityHandle entity_handle, const void* data );
00409 
00410     //! get the tag data for an entity id
00411     //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for
00412     //!      variable-length tag.
00413     inline ErrorCode get_data( Error*, EntityHandle entity_handle, void* data ) const;
00414 
00415     //! get the variable-length data for an entity id
00416     inline ErrorCode get_data_ptr( EntityHandle entity_handle, const void*& data, bool allocate = true ) const;
00417 
00418     //! removes the data
00419     inline ErrorCode remove_data( Error*, EntityHandle entity_handle );
00420 
00421     //! allocator for this collection
00422     SparseTagDataAllocator mAllocator;
00423 
00424     MapType mData;
00425 };
00426 
00427 inline void* SparseTag::allocate_data( EntityHandle h,
00428 #ifdef MOAB_HAVE_UNORDERED_MAP
00429                                        MapType::const_iterator iter,
00430 #else
00431                                        MapType::const_iterator,
00432 #endif
00433                                        bool copy_default )
00434 {
00435     void* new_data = mAllocator.allocate( get_size() );
00436 #ifdef MOAB_HAVE_UNORDERED_MAP
00437     mData.insert( iter, std::pair< const EntityHandle, void* >( h, new_data ) );
00438 #else
00439     mData[h] = new_data;
00440 #endif
00441     if( copy_default ) memcpy( new_data, get_default_value(), get_size() );
00442     return new_data;
00443 }
00444 
00445 }  // namespace moab
00446 
00447 #endif  // SPARSE_TAG_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines