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