Branch data Line data Source code
1 : : #ifndef BIT_TAG_HPP
2 : : #define BIT_TAG_HPP
3 : :
4 : : #include "TagInfo.hpp"
5 : : #include "Internals.hpp"
6 : : #include <algorithm>
7 : : #include <vector>
8 : : #include <assert.h>
9 : :
10 : : namespace moab
11 : : {
12 : :
13 : : class BitPage;
14 : :
15 : : /**\brief data for a single bit tag */
16 : : class BitTag : public TagInfo
17 : : {
18 : : private:
19 : 160 : BitTag( const char* name, int size, const void* default_value )
20 : : : TagInfo( name, size, MB_TYPE_BIT, default_value, default_value ? 1 : 0 ), requestedBitsPerEntity( 0 ),
21 [ + + ][ + - ]: 2080 : storedBitsPerEntity( 0 ), pageShift( 0 )
[ + + # # ]
22 : : {
23 [ # # ]: 160 : }
24 : :
25 : : public:
26 : : static BitTag* create_tag( const char* name, int size, const void* default_value = 0 );
27 : :
28 : : virtual ~BitTag();
29 : :
30 : : virtual TagType get_storage_type() const;
31 : :
32 : : /**\brief Remove/clear tag data for all entities
33 : : *
34 : : * Remove tag values from entities.
35 : : *
36 : : *\param delete_pending If true, then release any global
37 : : * data associated with the tag in preparation for deleting
38 : : * the tag itself.
39 : : *
40 : : *\Note Invalidates tag if \c tag_delete_pending is true. The only
41 : : * valid method that can be invoked that is is the destructor.
42 : : *
43 : : *\param seqman Pointer to mesh entity database
44 : : */
45 : : virtual ErrorCode release_all_data( SequenceManager* seqman, Error* error_handler, bool delete_pending );
46 : :
47 : : /**\brief Get tag value for passed entities
48 : : *
49 : : * Get tag values for specified entities.
50 : : *
51 : : *\Note Will fail for variable-length data.
52 : : *\param seqman Pointer to mesh entity database
53 : : *\param entities Entity handles for which to retrieve tag data
54 : : *\param num_entities Length of \c entities array
55 : : *\param data Pointer to memory in which to store consecutive tag values,
56 : : * one for each passed entity.
57 : : */
58 : : virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
59 : : size_t num_entities, void* data ) const;
60 : :
61 : : /**\brief Get tag value for passed entities
62 : : *
63 : : * Get tag values for specified entities.
64 : : *
65 : : *\Note Will fail for variable-length data.
66 : : *\param seqman Pointer to mesh entity database
67 : : *\param entities Entity handles for which to retrieve tag data
68 : : *\param data Pointer to memory in which to store consecutive tag values,
69 : : * one for each passed entity.
70 : : */
71 : : virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const Range& entities,
72 : : void* data ) const;
73 : :
74 : : /**\brief Get tag value for passed entities
75 : : *
76 : : * Get tag values for specified entities.
77 : : *
78 : : *\param seqman Pointer to mesh entity database
79 : : *\param entities Entity handles for which to retrieve tag data
80 : : *\param num_entities Length of \c entities array
81 : : *\param data_ptrs Array of pointers to tag values, one pointer
82 : : * for each passed entity.
83 : : *\param data_lengths One value for each entity specifying the
84 : : * length of the tag value for the corresponding
85 : : * entity.
86 : : */
87 : : virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
88 : : size_t num_entities, const void** data_ptrs, int* data_lengths ) const;
89 : :
90 : : /**\brief Get tag value for passed entities
91 : : *
92 : : * Get tag values for specified entities.
93 : : *
94 : : *\param seqman Pointer to mesh entity database
95 : : *\param entities Entity handles for which to retrieve tag data
96 : : *\param data_ptrs Array of pointers to tag values, one pointer
97 : : * for each passed entity.
98 : : *\param data_lengths One value for each entity specifying the
99 : : * length of the tag value for the corresponding
100 : : * entity.
101 : : */
102 : : virtual ErrorCode get_data( const SequenceManager* seqman, Error* error_handler, const Range& entities,
103 : : const void** data_ptrs, int* data_lengths ) const;
104 : :
105 : : /**\brief Set tag value for passed entities
106 : : *
107 : : * Store tag data or update stored tag values
108 : : *\Note Will fail for variable-length data.
109 : : *\param seqman Pointer to mesh entity database
110 : : *\param entities Entity handles for which to store tag data
111 : : *\param num_entities Length of \c entities array
112 : : *\param data Pointer to memory holding consecutive tag values,
113 : : * one for each passed entity.
114 : : */
115 : : virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
116 : : size_t num_entities, const void* data );
117 : :
118 : : /**\brief Set tag value for passed entities
119 : : *
120 : : * Store tag data or update stored tag values
121 : : *\Note Will fail for variable-length data.
122 : : *\param seqman Pointer to mesh entity database
123 : : *\param entities Entity handles for which to store tag data
124 : : *\param data Pointer to memory holding consecutive tag values,
125 : : * one for each passed entity.
126 : : */
127 : : virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const Range& entities,
128 : : const void* data );
129 : :
130 : : /**\brief Set tag value for passed entities
131 : : *
132 : : * Store tag data or update stored tag values
133 : : *
134 : : *\param seqman Pointer to mesh entity database
135 : : *\param entities Entity handles for which to store tag data
136 : : *\param num_entities Length of \c entities array
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. Array is required for variable-length
142 : : * tags and is ignored for fixed-length tags.
143 : : */
144 : : virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
145 : : size_t num_entities, void const* const* data_ptrs, const int* data_lengths );
146 : :
147 : : /**\brief Set tag value for passed entities
148 : : *
149 : : * Store tag data or update stored tag values
150 : : *
151 : : *\param seqman Pointer to mesh entity database
152 : : *\param entities Entity handles for which to store tag data
153 : : *\param data_ptrs Array of pointers to tag values, one pointer
154 : : * for each passed entity.
155 : : *\param data_lengths One value for each entity specifying the
156 : : * length of the tag value for the corresponding
157 : : * entity. Array is required for variable-length
158 : : * tags and is ignored for fixed-length tags.
159 : : */
160 : : virtual ErrorCode set_data( SequenceManager* seqman, Error* error_handler, const Range& entities,
161 : : void const* const* data_ptrs, const int* data_lengths );
162 : :
163 : : /**\brief Set tag value for passed entities
164 : : *
165 : : * Store tag data or update stored tag values.
166 : : *
167 : : *\param seqman Pointer to mesh entity database
168 : : *\param entities Entity handles for which to store tag data
169 : : *\param num_entities Length of \c entities array
170 : : *\param value_ptr Pointer to a single tag value which is to be
171 : : * stored for each of the passed entities.
172 : : *\param value_len Length of tag value in bytes. Ignored for
173 : : * fixed-length tags. Required for variable-
174 : : * length tags.
175 : : */
176 : : virtual ErrorCode clear_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
177 : : size_t num_entities, const void* value_ptr, int value_len = 0 );
178 : :
179 : : /**\brief Set tag value for passed entities
180 : : *
181 : : * Store tag data or update stored tag values.
182 : : *
183 : : *\param seqman Pointer to mesh entity database
184 : : *\param entities Entity handles for which to store tag data
185 : : *\param value_ptr Pointer to a single tag value which is to be
186 : : * stored for each of the passed entities.
187 : : *\param value_len Length of tag value in bytes. Ignored for
188 : : * fixed-length tags. Required for variable-
189 : : * length tags.
190 : : */
191 : : virtual ErrorCode clear_data( SequenceManager* seqman, Error* error_handler, const Range& entities,
192 : : const void* value_ptr, int value_len = 0 );
193 : :
194 : : /**\brief Remove/clear tag data for entities
195 : : *
196 : : * Remove tag values from entities.
197 : : *
198 : : *\param seqman Pointer to mesh entity database
199 : : *\param entities Entity handles for which to store tag data
200 : : *\param num_entities Length of \c entities array
201 : : */
202 : : virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const EntityHandle* entities,
203 : : size_t num_entities );
204 : :
205 : : /**\brief Remove/clear tag data for entities
206 : : *
207 : : * Remove tag values from entities.
208 : : *
209 : : *\param seqman Pointer to mesh entity database
210 : : *\param entities Entity handles for which to store tag data
211 : : */
212 : : virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const Range& entities );
213 : :
214 : : /**\brief Access tag data via direct pointer into contiguous blocks
215 : : *
216 : : * Iteratively obtain direct access to contiguous blocks of tag
217 : : * storage. This function cannot be used with bit tags because
218 : : * of the compressed bit storage. This function cannot be used
219 : : * with variable length tags because it does not provide a mechanism
220 : : * to determine the length of the value for each entity. This
221 : : * function may be used with sparse tags, but if it is used, it
222 : : * will return data for a single entity at a time.
223 : : *
224 : : *\param iter As input, the first entity for which to return
225 : : * data. As output, one past the last entity for
226 : : * which data was returned.
227 : : *\param end One past the last entity for which data is desired
228 : : *\param data_ptr Output: pointer to tag storage.
229 : : *
230 : : *\Note If this function is called for entities for which no tag value
231 : : * has been set, but for which a default value exists, it will
232 : : * force the allocation of explicit storage for each such entity
233 : : * even though MOAB would normally not explicitly store tag values
234 : : * for such entities.
235 : : */
236 : : virtual ErrorCode tag_iterate( SequenceManager* seqman, Error* error_handler, Range::iterator& iter,
237 : : const Range::iterator& end, void*& data_ptr, bool allocate = true );
238 : :
239 : : /**\brief Get all tagged entities
240 : : *
241 : : * Get the list of entities for which the a tag value has been set,
242 : : * or a close approximation if the tag storage scheme cannot
243 : : * accurately determine exactly which entities have explicit values.
244 : : *
245 : : *\param seqman Pointer to entity storage database
246 : : *\param output_entities Results *appended* to this range
247 : : *\param type Optional entity type. If specified, search is
248 : : * limited to entities of specified type.
249 : : *\param intersect Optional intersect list. If specified,
250 : : * search is restricted to entities in this list.
251 : : */
252 : : virtual ErrorCode get_tagged_entities( const SequenceManager* seqman, Range& output_entities,
253 : : EntityType type = MBMAXTYPE, const Range* intersect = 0 ) const;
254 : :
255 : : /**\brief Count all tagged entities
256 : : *
257 : : * Count the entities for which the a tag value has been set,
258 : : * or a close approximation if the tag storage scheme cannot
259 : : * accurately determine exactly which entities have explicit values.
260 : : *
261 : : *\param seqman Pointer to entity storage database
262 : : *\param output_count This is *incremented* for each detected entity.
263 : : *\param type Optional entity type. If specified, search is
264 : : * limited to entities of specified type.
265 : : *\param intersect Optional intersect list. If specified,
266 : : * search is restricted to entities in this list.
267 : : */
268 : : virtual ErrorCode num_tagged_entities( const SequenceManager* seqman, size_t& output_count,
269 : : EntityType type = MBMAXTYPE, const Range* intersect = 0 ) const;
270 : :
271 : : /**\brief Get all tagged entities with tag value
272 : : *
273 : : * Get the list of entities which have the specified tag value.
274 : : *
275 : : *\param seqman Pointer to entity storage database
276 : : *\param output_entities Results *appended* to this range
277 : : *\param value Pointer to tag value
278 : : *\param value_bytes Size of tag value in bytes.
279 : : *\param type Optional entity type. If specified, search is
280 : : * limited to entities of specified type.
281 : : *\param intersect_entities Optional intersect list. If specified,
282 : : * search is restricted to entities in this list.
283 : : */
284 : : virtual ErrorCode find_entities_with_value( const SequenceManager* seqman, Error* error_handler,
285 : : Range& output_entities, const void* value, int value_bytes = 0,
286 : : EntityType type = MBMAXTYPE,
287 : : const Range* intersect_entities = 0 ) const;
288 : :
289 : : /**\brief Check if entity is tagged */
290 : : virtual bool is_tagged( const SequenceManager*, EntityHandle h ) const;
291 : :
292 : : /**\brief Get memory use for tag data.
293 : : *
294 : : */
295 : : ErrorCode get_memory_use( const SequenceManager* seqman, unsigned long& total, unsigned long& per_entity ) const;
296 : :
297 : : /**\brief Get entities for which an explicit tag of the specified value is stored */
298 : : ErrorCode get_entities_with_bits( EntityType type, Range& entities, unsigned char bits ) const;
299 : :
300 : : /**\brief Get entities for which an explicit tag of the specified value is stored */
301 : : ErrorCode get_entities_with_bits( const Range& range, EntityType type, Range& entities, unsigned char bits ) const;
302 : :
303 : : enum
304 : : {
305 : : Ln2PageSize = 12, //!< Constant: log2(PageSize)
306 : : PageSize = ( 1u << Ln2PageSize ) //!< Constant: Bytes per BitPage (power of 2)
307 : : };
308 : :
309 : : private:
310 : : BitTag( const BitTag& );
311 : : BitTag& operator=( const BitTag& );
312 : : ErrorCode reserve( unsigned bits );
313 : :
314 : 2521157 : inline unsigned char default_val() const
315 : : {
316 [ + + ]: 2521157 : if( get_default_value() )
317 : 86168 : return *reinterpret_cast< const unsigned char* >( get_default_value() );
318 : : else
319 : 2434989 : return 0;
320 : : }
321 : :
322 : : std::vector< BitPage* > pageList[MBMAXTYPE]; //!< Array of BitPage instances storing actual data.
323 : : unsigned int requestedBitsPerEntity; //!< user-requested bits per entity
324 : : unsigned int storedBitsPerEntity; //!< allocated bits per entity (power of 2)
325 : : unsigned int pageShift; //!< log2( ents_per_page() )
326 : :
327 : : /**\brief Get indices from handle
328 : : *
329 : : *\param type Output: entity type
330 : : *\param page Output: index into pageList[type]
331 : : *\param offset Output: index into pageList[type][page]
332 : : */
333 : 6843941 : void unpack( EntityHandle h, EntityType& type, size_t& page, int& offset ) const
334 : : {
335 : 6843941 : type = TYPE_FROM_HANDLE( h );
336 : 6843941 : h = ID_FROM_HANDLE( h );
337 : 6843941 : page = ( (size_t)h ) >> pageShift; // h / ents_per_page()
338 : 6843941 : offset = h & ( ( 1u << pageShift ) - 1u ); // h % ends_per_page()
339 : 6843941 : }
340 : :
341 : : /**\brief Get the number of tag values that are stored in each BitPage */
342 : 65 : int ents_per_page() const
343 : : {
344 : 65 : return 8 * PageSize / storedBitsPerEntity;
345 : : }
346 : :
347 : : template < class Container >
348 : : inline void get_tagged( EntityType type, Container& entities ) const;
349 : : template < class Container >
350 : : inline void get_tagged( Range::const_iterator begin, Range::const_iterator end, Container& entities ) const;
351 : : template < class Container >
352 : : inline void get_tagged( Container& entities, EntityType type, const Range* intersect ) const;
353 : : };
354 : :
355 : : } // namespace moab
356 : :
357 : : #endif
|