MOAB: Mesh Oriented datABase
(version 5.4.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 <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