MOAB: Mesh Oriented datABase
(version 5.2.1)
|
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