MOAB: Mesh Oriented datABase
(version 5.2.1)
|
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 <assert.h> 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, Error* error_handler, const EntityHandle* entities, 00059 size_t num_entities, void* data ) const; 00060 00061 /**\brief Get tag value for passed entities 00062 * 00063 * Get tag values for specified entities. 00064 * 00065 *\Note Will fail for variable-length data. 00066 *\param seqman Pointer to mesh entity database 00067 *\param entities Entity handles for which to retrieve tag data 00068 *\param data Pointer to memory in which to store consecutive tag values, 00069 * one for each passed entity. 00070 */ 00071 virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const Range& entities, 00072 void* data ) const; 00073 00074 /**\brief Get tag value for passed entities 00075 * 00076 * Get tag values for specified entities. 00077 * 00078 *\param seqman Pointer to mesh entity database 00079 *\param entities Entity handles for which to retrieve tag data 00080 *\param num_entities Length of \c entities array 00081 *\param data_ptrs Array of pointers to tag values, one pointer 00082 * for each passed entity. 00083 *\param data_lengths One value for each entity specifying the 00084 * length of the tag value for the corresponding 00085 * entity. 00086 */ 00087 virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const EntityHandle* entities, 00088 size_t num_entities, const void** data_ptrs, int* data_lengths ) const; 00089 00090 /**\brief Get tag value for passed entities 00091 * 00092 * Get tag values for specified entities. 00093 * 00094 *\param seqman Pointer to mesh entity database 00095 *\param entities Entity handles for which to retrieve tag data 00096 *\param data_ptrs Array of pointers to tag values, one pointer 00097 * for each passed entity. 00098 *\param data_lengths One value for each entity specifying the 00099 * length of the tag value for the corresponding 00100 * entity. 00101 */ 00102 virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const Range& entities, 00103 const void** data_ptrs, int* data_lengths ) const; 00104 00105 /**\brief Set tag value for passed entities 00106 * 00107 * Store tag data or update stored tag values 00108 *\Note Will fail for variable-length data. 00109 *\param seqman Pointer to mesh entity database 00110 *\param entities Entity handles for which to store tag data 00111 *\param num_entities Length of \c entities array 00112 *\param data Pointer to memory holding consecutive tag values, 00113 * one for each passed entity. 00114 */ 00115 virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities, 00116 size_t num_entities, const void* data ); 00117 00118 /**\brief Set tag value for passed entities 00119 * 00120 * Store tag data or update stored tag values 00121 *\Note Will fail for variable-length data. 00122 *\param seqman Pointer to mesh entity database 00123 *\param entities Entity handles for which to store tag data 00124 *\param data Pointer to memory holding consecutive tag values, 00125 * one for each passed entity. 00126 */ 00127 virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const Range& entities, 00128 const void* data ); 00129 00130 /**\brief Set tag value for passed entities 00131 * 00132 * Store tag data or update stored tag values 00133 * 00134 *\param seqman Pointer to mesh entity database 00135 *\param entities Entity handles for which to store tag data 00136 *\param num_entities Length of \c entities array 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. Array is required for variable-length 00142 * tags and is ignored for fixed-length tags. 00143 */ 00144 virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities, 00145 size_t num_entities, void const* const* data_ptrs, const int* data_lengths ); 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 data_ptrs Array of pointers to tag values, one pointer 00154 * for each passed entity. 00155 *\param data_lengths One value for each entity specifying the 00156 * length of the tag value for the corresponding 00157 * entity. Array is required for variable-length 00158 * tags and is ignored for fixed-length tags. 00159 */ 00160 virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const Range& entities, 00161 void const* const* data_ptrs, const int* data_lengths ); 00162 00163 /**\brief Set tag value for passed entities 00164 * 00165 * Store tag data or update stored tag values. 00166 * 00167 *\param seqman Pointer to mesh entity database 00168 *\param entities Entity handles for which to store tag data 00169 *\param num_entities Length of \c entities array 00170 *\param value_ptr Pointer to a single tag value which is to be 00171 * stored for each of the passed entities. 00172 *\param value_len Length of tag value in bytes. Ignored for 00173 * fixed-length tags. Required for variable- 00174 * length tags. 00175 */ 00176 virtual ErrorCode clear_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities, 00177 size_t num_entities, const void* value_ptr, int value_len = 0 ); 00178 00179 /**\brief Set tag value for passed entities 00180 * 00181 * Store tag data or update stored tag values. 00182 * 00183 *\param seqman Pointer to mesh entity database 00184 *\param entities Entity handles for which to store tag data 00185 *\param value_ptr Pointer to a single tag value which is to be 00186 * stored for each of the passed entities. 00187 *\param value_len Length of tag value in bytes. Ignored for 00188 * fixed-length tags. Required for variable- 00189 * length tags. 00190 */ 00191 virtual ErrorCode clear_data( SequenceManager* seqman, Error* error_handler, const Range& entities, 00192 const void* value_ptr, int value_len = 0 ); 00193 00194 /**\brief Remove/clear tag data for entities 00195 * 00196 * Remove tag values from entities. 00197 * 00198 *\param seqman Pointer to mesh entity database 00199 *\param entities Entity handles for which to store tag data 00200 *\param num_entities Length of \c entities array 00201 */ 00202 virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities, 00203 size_t num_entities ); 00204 00205 /**\brief Remove/clear tag data for entities 00206 * 00207 * Remove tag values from entities. 00208 * 00209 *\param seqman Pointer to mesh entity database 00210 *\param entities Entity handles for which to store tag data 00211 */ 00212 virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const Range& entities ); 00213 00214 /**\brief Access tag data via direct pointer into contiguous blocks 00215 * 00216 * Iteratively obtain direct access to contiguous blocks of tag 00217 * storage. This function cannot be used with bit tags because 00218 * of the compressed bit storage. This function cannot be used 00219 * with variable length tags because it does not provide a mechanism 00220 * to determine the length of the value for each entity. This 00221 * function may be used with sparse tags, but if it is used, it 00222 * will return data for a single entity at a time. 00223 * 00224 *\param iter As input, the first entity for which to return 00225 * data. As output, one past the last entity for 00226 * which data was returned. 00227 *\param end One past the last entity for which data is desired 00228 *\param data_ptr Output: pointer to tag storage. 00229 * 00230 *\Note If this function is called for entities for which no tag value 00231 * has been set, but for which a default value exists, it will 00232 * force the allocation of explicit storage for each such entity 00233 * even though MOAB would normally not explicitly store tag values 00234 * for such entities. 00235 */ 00236 virtual ErrorCode tag_iterate( SequenceManager* seqman, Error* error_handler, Range::iterator& iter, 00237 const Range::iterator& end, void*& data_ptr, bool allocate = true ); 00238 00239 /**\brief Get all tagged entities 00240 * 00241 * Get the list of entities for which the a tag value has been set, 00242 * or a close approximation if the tag storage scheme cannot 00243 * accurately determine exactly which entities have explicit values. 00244 * 00245 *\param seqman Pointer to entity storage database 00246 *\param output_entities Results *appended* to this range 00247 *\param type Optional entity type. If specified, search is 00248 * limited to entities of specified type. 00249 *\param intersect Optional intersect list. If specified, 00250 * search is restricted to entities in this list. 00251 */ 00252 virtual ErrorCode get_tagged_entities( const SequenceManager* seqman, Range& output_entities, 00253 EntityType type = MBMAXTYPE, const Range* intersect = 0 ) const; 00254 00255 /**\brief Count all tagged entities 00256 * 00257 * Count the entities for which the a tag value has been set, 00258 * or a close approximation if the tag storage scheme cannot 00259 * accurately determine exactly which entities have explicit values. 00260 * 00261 *\param seqman Pointer to entity storage database 00262 *\param output_count This is *incremented* for each detected entity. 00263 *\param type Optional entity type. If specified, search is 00264 * limited to entities of specified type. 00265 *\param intersect Optional intersect list. If specified, 00266 * search is restricted to entities in this list. 00267 */ 00268 virtual ErrorCode num_tagged_entities( const SequenceManager* seqman, size_t& output_count, 00269 EntityType type = MBMAXTYPE, const Range* intersect = 0 ) const; 00270 00271 /**\brief Get all tagged entities with tag value 00272 * 00273 * Get the list of entities which have the specified tag value. 00274 * 00275 *\param seqman Pointer to entity storage database 00276 *\param output_entities Results *appended* to this range 00277 *\param value Pointer to tag value 00278 *\param value_bytes Size of tag value in bytes. 00279 *\param type Optional entity type. If specified, search is 00280 * limited to entities of specified type. 00281 *\param intersect_entities Optional intersect list. If specified, 00282 * search is restricted to entities in this list. 00283 */ 00284 virtual ErrorCode find_entities_with_value( const SequenceManager* seqman, Error* error_handler, 00285 Range& output_entities, const void* value, int value_bytes = 0, 00286 EntityType type = MBMAXTYPE, 00287 const Range* intersect_entities = 0 ) const; 00288 00289 /**\brief Check if entity is tagged */ 00290 virtual bool is_tagged( const SequenceManager*, EntityHandle h ) const; 00291 00292 /**\brief Get memory use for tag data. 00293 * 00294 */ 00295 ErrorCode get_memory_use( const SequenceManager* seqman, unsigned long& total, unsigned long& per_entity ) const; 00296 00297 /**\brief Get entities for which an explicit tag of the specified value is stored */ 00298 ErrorCode get_entities_with_bits( EntityType type, Range& entities, unsigned char bits ) const; 00299 00300 /**\brief Get entities for which an explicit tag of the specified value is stored */ 00301 ErrorCode get_entities_with_bits( const Range& range, EntityType type, Range& entities, unsigned char bits ) const; 00302 00303 enum 00304 { 00305 Ln2PageSize = 12, //!< Constant: log2(PageSize) 00306 PageSize = ( 1u << Ln2PageSize ) //!< Constant: Bytes per BitPage (power of 2) 00307 }; 00308 00309 private: 00310 BitTag( const BitTag& ); 00311 BitTag& operator=( const BitTag& ); 00312 ErrorCode reserve( unsigned bits ); 00313 00314 inline unsigned char default_val() const 00315 { 00316 if( get_default_value() ) 00317 return *reinterpret_cast< const unsigned char* >( get_default_value() ); 00318 else 00319 return 0; 00320 } 00321 00322 std::vector< BitPage* > pageList[MBMAXTYPE]; //!< Array of BitPage instances storing actual data. 00323 unsigned int requestedBitsPerEntity; //!< user-requested bits per entity 00324 unsigned int storedBitsPerEntity; //!< allocated bits per entity (power of 2) 00325 unsigned int pageShift; //!< log2( ents_per_page() ) 00326 00327 /**\brief Get indices from handle 00328 * 00329 *\param type Output: entity type 00330 *\param page Output: index into pageList[type] 00331 *\param offset Output: index into pageList[type][page] 00332 */ 00333 void unpack( EntityHandle h, EntityType& type, size_t& page, int& offset ) const 00334 { 00335 type = TYPE_FROM_HANDLE( h ); 00336 h = ID_FROM_HANDLE( h ); 00337 page = ( (size_t)h ) >> pageShift; // h / ents_per_page() 00338 offset = h & ( ( 1u << pageShift ) - 1u ); // h % ends_per_page() 00339 } 00340 00341 /**\brief Get the number of tag values that are stored in each BitPage */ 00342 int ents_per_page() const 00343 { 00344 return 8 * PageSize / storedBitsPerEntity; 00345 } 00346 00347 template < class Container > 00348 inline void get_tagged( EntityType type, Container& entities ) const; 00349 template < class Container > 00350 inline void get_tagged( Range::const_iterator begin, Range::const_iterator end, Container& entities ) const; 00351 template < class Container > 00352 inline void get_tagged( Container& entities, EntityType type, const Range* intersect ) const; 00353 }; 00354 00355 } // namespace moab 00356 00357 #endif