Branch data Line data Source code
1 : : /**
2 : : * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 : : * storing and accessing finite element mesh data.
4 : : *
5 : : * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 : : * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7 : : * retains certain rights in this software.
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : */
15 : :
16 : : #ifndef SPARSE_TAG_HPP
17 : : #define SPARSE_TAG_HPP
18 : :
19 : : #ifndef IS_BUILDING_MB
20 : : #error "SparseTag.hpp isn't supposed to be included into an application"
21 : : #endif
22 : :
23 : : #ifdef WIN32
24 : : #pragma warning( disable : 4786 )
25 : : #endif
26 : :
27 : : #include "moab/MOABConfig.h"
28 : : #define STRINGIFY_( X ) #X
29 : : #define STRINGIFY( X ) STRINGIFY_( X )
30 : : #ifdef MOAB_HAVE_UNORDERED_MAP
31 : : #include STRINGIFY( MOAB_HAVE_UNORDERED_MAP )
32 : : #else
33 : : #include <map>
34 : : #endif
35 : : #include <vector>
36 : :
37 : : #include "TagInfo.hpp"
38 : : #include <stdlib.h>
39 : :
40 : : namespace moab
41 : : {
42 : :
43 : : //! allocator for tag data
44 : : class SparseTagDataAllocator
45 : : {
46 : : public:
47 : : //! constructor
48 : 2119 : SparseTagDataAllocator() {}
49 : : //! destructor
50 : 2094 : ~SparseTagDataAllocator() {}
51 : : //! allocates memory of size and returns pointer
52 : 7162 : void* allocate( size_t data_size )
53 : : {
54 : 7162 : return malloc( data_size );
55 : : }
56 : : //! frees the memory
57 : 6921 : void destroy( void* p )
58 : : {
59 : 6921 : free( p );
60 : 6921 : }
61 : : };
62 : :
63 : : //! Sparse tag data
64 : : class SparseTag : public TagInfo
65 : : {
66 : : public:
67 : : SparseTag( const char* name, int size, DataType type, const void* default_value );
68 : :
69 : : ~SparseTag();
70 : :
71 : : virtual TagType get_storage_type() const;
72 : :
73 : : /**\brief Remove/clear tag data for all entities
74 : : *
75 : : * Remove tag values from entities.
76 : : *
77 : : *\param delete_pending If true, then release any global
78 : : * data associated with the tag in preparation for deleting
79 : : * the tag itself.
80 : : *
81 : : *\Note Invalidates tag if \c tag_delete_pending is true. The only
82 : : * valid method that can be invoked that is is the destructor.
83 : : *
84 : : *\param seqman Pointer to mesh entity database
85 : : */
86 : : virtual ErrorCode release_all_data( SequenceManager* seqman, Error* error_handler, bool delete_pending );
87 : :
88 : : /**\brief Get tag value for passed entities
89 : : *
90 : : * Get tag values for specified entities.
91 : : *
92 : : *\Note Will fail for variable-length data.
93 : : *\param seqman Pointer to mesh entity database
94 : : *\param entities Entity handles for which to retrieve tag data
95 : : *\param num_entities Length of \c entities array
96 : : *\param data Pointer to memory in which to store consecutive tag values,
97 : : * one for each passed entity.
98 : : */
99 : : virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
100 : : size_t num_entities, void* data ) const;
101 : :
102 : : /**\brief Get tag value for passed entities
103 : : *
104 : : * Get tag values for specified entities.
105 : : *
106 : : *\Note Will fail for variable-length data.
107 : : *\param seqman Pointer to mesh entity database
108 : : *\param entities Entity handles for which to retrieve tag data
109 : : *\param data Pointer to memory in which to store consecutive tag values,
110 : : * one for each passed entity.
111 : : */
112 : : virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const Range& entities,
113 : : void* data ) const;
114 : :
115 : : /**\brief Get tag value for passed entities
116 : : *
117 : : * Get tag values for specified entities.
118 : : *
119 : : *\param seqman Pointer to mesh entity database
120 : : *\param entities Entity handles for which to retrieve tag data
121 : : *\param num_entities Length of \c entities array
122 : : *\param data_ptrs Array of pointers to tag values, one pointer
123 : : * for each passed entity.
124 : : *\param data_lengths One value for each entity specifying the
125 : : * length of the tag value for the corresponding
126 : : * entity.
127 : : */
128 : : virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
129 : : size_t num_entities, const void** data_ptrs, int* data_lengths ) const;
130 : :
131 : : /**\brief Get tag value for passed entities
132 : : *
133 : : * Get tag values for specified entities.
134 : : *
135 : : *\param seqman Pointer to mesh entity database
136 : : *\param entities Entity handles for which to retrieve tag data
137 : : *\param data_ptrs Array of pointers to tag values, one pointer
138 : : * for each passed entity.
139 : : *\param data_lengths One value for each entity specifying the
140 : : * length of the tag value for the corresponding
141 : : * entity.
142 : : */
143 : : virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const Range& entities,
144 : : const void** data_ptrs, int* data_lengths ) const;
145 : :
146 : : /**\brief Set tag value for passed entities
147 : : *
148 : : * Store tag data or update stored tag values
149 : : *\Note Will fail for variable-length data.
150 : : *\param seqman Pointer to mesh entity database
151 : : *\param entities Entity handles for which to store tag data
152 : : *\param num_entities Length of \c entities array
153 : : *\param data Pointer to memory holding consecutive tag values,
154 : : * one for each passed entity.
155 : : */
156 : : virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
157 : : size_t num_entities, const void* data );
158 : :
159 : : /**\brief Set tag value for passed entities
160 : : *
161 : : * Store tag data or update stored tag values
162 : : *\Note Will fail for variable-length data.
163 : : *\param seqman Pointer to mesh entity database
164 : : *\param entities Entity handles for which to store tag data
165 : : *\param data Pointer to memory holding consecutive tag values,
166 : : * one for each passed entity.
167 : : */
168 : : virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const Range& entities,
169 : : const void* data );
170 : :
171 : : /**\brief Set tag value for passed entities
172 : : *
173 : : * Store tag data or update stored tag values
174 : : *
175 : : *\param seqman Pointer to mesh entity database
176 : : *\param entities Entity handles for which to store tag data
177 : : *\param num_entities Length of \c entities array
178 : : *\param data_ptrs Array of pointers to tag values, one pointer
179 : : * for each passed entity.
180 : : *\param data_lengths One value for each entity specifying the
181 : : * length of the tag value for the corresponding
182 : : * entity. Array is required for variable-length
183 : : * tags and is ignored for fixed-length tags.
184 : : */
185 : : virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
186 : : size_t num_entities, void const* const* data_ptrs, const int* data_lengths );
187 : :
188 : : /**\brief Set tag value for passed entities
189 : : *
190 : : * Store tag data or update stored tag values
191 : : *
192 : : *\param seqman Pointer to mesh entity database
193 : : *\param entities Entity handles for which to store tag data
194 : : *\param data_ptrs Array of pointers to tag values, one pointer
195 : : * for each passed entity.
196 : : *\param data_lengths One value for each entity specifying the
197 : : * length of the tag value for the corresponding
198 : : * entity. Array is required for variable-length
199 : : * tags and is ignored for fixed-length tags.
200 : : */
201 : : virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const Range& entities,
202 : : void const* const* data_ptrs, const int* data_lengths );
203 : :
204 : : /**\brief Set tag value for passed entities
205 : : *
206 : : * Store tag data or update stored tag values.
207 : : *
208 : : *\param seqman Pointer to mesh entity database
209 : : *\param entities Entity handles for which to store tag data
210 : : *\param num_entities Length of \c entities array
211 : : *\param value_ptr Pointer to a single tag value which is to be
212 : : * stored for each of the passed entities.
213 : : *\param value_len Length of tag value in bytes. Ignored for
214 : : * fixed-length tags. Required for variable-
215 : : * length tags.
216 : : */
217 : : virtual ErrorCode clear_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
218 : : size_t num_entities, const void* value_ptr, int value_len = 0 );
219 : :
220 : : /**\brief Set tag value for passed entities
221 : : *
222 : : * Store tag data or update stored tag values.
223 : : *
224 : : *\param seqman Pointer to mesh entity database
225 : : *\param entities Entity handles for which to store tag data
226 : : *\param value_ptr Pointer to a single tag value which is to be
227 : : * stored for each of the passed entities.
228 : : *\param value_len Length of tag value in bytes. Ignored for
229 : : * fixed-length tags. Required for variable-
230 : : * length tags.
231 : : */
232 : : virtual ErrorCode clear_data( SequenceManager* seqman, Error* error_handler, const Range& entities,
233 : : const void* value_ptr, int value_len = 0 );
234 : :
235 : : /**\brief Remove/clear tag data for entities
236 : : *
237 : : * Remove tag values from entities.
238 : : *
239 : : *\param seqman Pointer to mesh entity database
240 : : *\param entities Entity handles for which to store tag data
241 : : *\param num_entities Length of \c entities array
242 : : */
243 : : virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
244 : : size_t num_entities );
245 : :
246 : : /**\brief Remove/clear tag data for entities
247 : : *
248 : : * Remove tag values from entities.
249 : : *
250 : : *\param seqman Pointer to mesh entity database
251 : : *\param entities Entity handles for which to store tag data
252 : : */
253 : : virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const Range& entities );
254 : :
255 : : /**\brief Access tag data via direct pointer into contiguous blocks
256 : : *
257 : : * Iteratively obtain direct access to contiguous blocks of tag
258 : : * storage. This function cannot be used with bit tags because
259 : : * of the compressed bit storage. This function cannot be used
260 : : * with variable length tags because it does not provide a mechanism
261 : : * to determine the length of the value for each entity. This
262 : : * function may be used with sparse tags, but if it is used, it
263 : : * will return data for a single entity at a time.
264 : : *
265 : : *\param iter As input, the first entity for which to return
266 : : * data. As output, one past the last entity for
267 : : * which data was returned.
268 : : *\param end One past the last entity for which data is desired
269 : : *\param data_ptr Output: pointer to tag storage.
270 : : *\param allocate If true, space for this tag will be allocated, if not it wont
271 : : *
272 : : *\Note If this function is called for entities for which no tag value
273 : : * has been set, but for which a default value exists, it will
274 : : * force the allocation of explicit storage for each such entity
275 : : * even though MOAB would normally not explicitly store tag values
276 : : * for such entities.
277 : : */
278 : : virtual ErrorCode tag_iterate( SequenceManager* seqman, Error* error_handler, Range::iterator& iter,
279 : : const Range::iterator& end, void*& data_ptr, bool allocate = true );
280 : :
281 : : /**\brief Get all tagged entities
282 : : *
283 : : * Get the list of entities for which the a tag value has been set,
284 : : * or a close approximation if the tag storage scheme cannot
285 : : * accurately determine exactly which entities have explicit values.
286 : : *
287 : : *\param seqman Pointer to entity storage database
288 : : *\param output_entities Results *appended* to this range
289 : : *\param type Optional entity type. If specified, search is
290 : : * limited to entities of specified type.
291 : : *\param intersect Optional intersect list. If specified,
292 : : * search is restricted to entities in this list.
293 : : */
294 : : virtual ErrorCode get_tagged_entities( const SequenceManager* seqman, Range& output_entities,
295 : : EntityType type = MBMAXTYPE, const Range* intersect = 0 ) const;
296 : :
297 : : /**\brief Count all tagged entities
298 : : *
299 : : * Count the entities for which the a tag value has been set,
300 : : * or a close approximation if the tag storage scheme cannot
301 : : * accurately determine exactly which entities have explicit values.
302 : : *
303 : : *\param seqman Pointer to entity storage database
304 : : *\param output_count This is *incremented* for each detected entity.
305 : : *\param type Optional entity type. If specified, search is
306 : : * limited to entities of specified type.
307 : : *\param intersect Optional intersect list. If specified,
308 : : * search is restricted to entities in this list.
309 : : */
310 : : virtual ErrorCode num_tagged_entities( const SequenceManager* seqman, size_t& output_count,
311 : : EntityType type = MBMAXTYPE, const Range* intersect = 0 ) const;
312 : :
313 : : /**\brief Get all tagged entities with tag value
314 : : *
315 : : * Get the list of entities which have the specified tag value.
316 : : *
317 : : *\param seqman Pointer to entity storage database
318 : : *\param output_entities Results *appended* to this range
319 : : *\param value Pointer to tag value
320 : : *\param value_bytes Size of tag value in bytes.
321 : : *\param type Optional entity type. If specified, search is
322 : : * limited to entities of specified type.
323 : : *\param intersect_entities Optional intersect list. If specified,
324 : : * search is restricted to entities in this list.
325 : : */
326 : : virtual ErrorCode find_entities_with_value( const SequenceManager* seqman, Error* error_handler,
327 : : Range& output_entities, const void* value, int value_bytes = 0,
328 : : EntityType type = MBMAXTYPE,
329 : : const Range* intersect_entities = 0 ) const;
330 : :
331 : : /**\brief Check if entity is tagged */
332 : : virtual bool is_tagged( const SequenceManager*, EntityHandle h ) const;
333 : :
334 : : /**\brief Get memory use for tag data.
335 : : *
336 : : */
337 : : virtual ErrorCode get_memory_use( const SequenceManager* seqman, unsigned long& total,
338 : : unsigned long& per_entity ) const;
339 : :
340 : : //! get number of entities
341 : : unsigned long get_number_entities()
342 : : {
343 : : return mData.size();
344 : : }
345 : :
346 : : //! map of entity id and tag data
347 : : #ifdef MOAB_HAVE_UNORDERED_MAP
348 : : typedef MOAB_UNORDERED_MAP_NS::unordered_map< EntityHandle, void* > MapType;
349 : : #else
350 : : typedef std::map< EntityHandle, void* > MapType;
351 : : #endif
352 : :
353 : : private:
354 : : SparseTag( const SparseTag& );
355 : : SparseTag& operator=( const SparseTag& );
356 : :
357 : : //! allocate an entry for this sparse tag w/o setting its value (yet)
358 : : inline void* allocate_data( EntityHandle h, MapType::const_iterator iter, bool copy_default = true );
359 : :
360 : : //! set the tag data for an entity id
361 : : //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for
362 : : //! variable-length tag.
363 : : inline ErrorCode set_data( Error*, EntityHandle entity_handle, const void* data );
364 : :
365 : : //! get the tag data for an entity id
366 : : //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for
367 : : //! variable-length tag.
368 : : inline ErrorCode get_data( Error*, EntityHandle entity_handle, void* data ) const;
369 : :
370 : : //! get the variable-length data for an entity id
371 : : inline ErrorCode get_data_ptr( EntityHandle entity_handle, const void*& data, bool allocate = true ) const;
372 : :
373 : : //! removes the data
374 : : inline ErrorCode remove_data( Error*, EntityHandle entity_handle );
375 : :
376 : : //! allocator for this collection
377 : : SparseTagDataAllocator mAllocator;
378 : :
379 : : MapType mData;
380 : : };
381 : :
382 : 7162 : inline void* SparseTag::allocate_data( EntityHandle h,
383 : : #ifdef MOAB_HAVE_UNORDERED_MAP
384 : : MapType::const_iterator iter,
385 : : #else
386 : : MapType::const_iterator,
387 : : #endif
388 : : bool copy_default )
389 : : {
390 [ + - ][ + - ]: 7162 : void* new_data = mAllocator.allocate( get_size() );
391 : : #ifdef MOAB_HAVE_UNORDERED_MAP
392 [ + - ][ + - ]: 7162 : mData.insert( iter, std::pair< const EntityHandle, void* >( h, new_data ) );
393 : : #else
394 : : mData[h] = new_data;
395 : : #endif
396 [ + + ][ + - ]: 7162 : if( copy_default ) memcpy( new_data, get_default_value(), get_size() );
[ + - ]
397 : 7162 : return new_data;
398 : : }
399 : :
400 : : } // namespace moab
401 : :
402 : : #endif // SPARSE_TAG_HPP
|