Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
BitTag.hpp
Go to the documentation of this file.
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 <cassert>
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  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 ),
22  {
23  }
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,
59  Error* error_handler,
60  const EntityHandle* entities,
61  size_t num_entities,
62  void* data ) const;
63 
64  /**\brief Get tag value for passed entities
65  *
66  * Get tag values for specified entities.
67  *
68  *\Note Will fail for variable-length data.
69  *\param seqman Pointer to mesh entity database
70  *\param entities Entity handles for which to retrieve tag data
71  *\param data Pointer to memory in which to store consecutive tag values,
72  * one for each passed entity.
73  */
74  virtual ErrorCode get_data( const SequenceManager* seqman,
75  Error* error_handler,
76  const Range& entities,
77  void* data ) const;
78 
79  /**\brief Get tag value for passed entities
80  *
81  * Get tag values for specified entities.
82  *
83  *\param seqman Pointer to mesh entity database
84  *\param entities Entity handles for which to retrieve tag data
85  *\param num_entities Length of \c entities array
86  *\param data_ptrs Array of pointers to tag values, one pointer
87  * for each passed entity.
88  *\param data_lengths One value for each entity specifying the
89  * length of the tag value for the corresponding
90  * entity.
91  */
92  virtual ErrorCode get_data( const SequenceManager* seqman,
93  Error* error_handler,
94  const EntityHandle* entities,
95  size_t num_entities,
96  const void** data_ptrs,
97  int* data_lengths ) const;
98 
99  /**\brief Get tag value for passed entities
100  *
101  * Get tag values for specified entities.
102  *
103  *\param seqman Pointer to mesh entity database
104  *\param entities Entity handles for which to retrieve tag data
105  *\param data_ptrs Array of pointers to tag values, one pointer
106  * for each passed entity.
107  *\param data_lengths One value for each entity specifying the
108  * length of the tag value for the corresponding
109  * entity.
110  */
111  virtual ErrorCode get_data( const SequenceManager* seqman,
112  Error* error_handler,
113  const Range& entities,
114  const void** data_ptrs,
115  int* data_lengths ) const;
116 
117  /**\brief Set tag value for passed entities
118  *
119  * Store tag data or update stored tag values
120  *\Note Will fail for variable-length data.
121  *\param seqman Pointer to mesh entity database
122  *\param entities Entity handles for which to store tag data
123  *\param num_entities Length of \c entities array
124  *\param data Pointer to memory holding consecutive tag values,
125  * one for each passed entity.
126  */
127  virtual ErrorCode set_data( SequenceManager* seqman,
128  Error* error_handler,
129  const EntityHandle* entities,
130  size_t num_entities,
131  const void* data );
132 
133  /**\brief Set tag value for passed entities
134  *
135  * Store tag data or update stored tag values
136  *\Note Will fail for variable-length data.
137  *\param seqman Pointer to mesh entity database
138  *\param entities Entity handles for which to store tag data
139  *\param data Pointer to memory holding consecutive tag values,
140  * one for each passed entity.
141  */
142  virtual ErrorCode set_data( SequenceManager* seqman,
143  Error* error_handler,
144  const Range& entities,
145  const void* data );
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 num_entities Length of \c entities array
154  *\param data_ptrs Array of pointers to tag values, one pointer
155  * for each passed entity.
156  *\param data_lengths One value for each entity specifying the
157  * length of the tag value for the corresponding
158  * entity. Array is required for variable-length
159  * tags and is ignored for fixed-length tags.
160  */
161  virtual ErrorCode set_data( SequenceManager* seqman,
162  Error* error_handler,
163  const EntityHandle* entities,
164  size_t num_entities,
165  void const* const* data_ptrs,
166  const int* data_lengths );
167 
168  /**\brief Set tag value for passed entities
169  *
170  * Store tag data or update stored tag values
171  *
172  *\param seqman Pointer to mesh entity database
173  *\param entities Entity handles for which to store tag data
174  *\param data_ptrs Array of pointers to tag values, one pointer
175  * for each passed entity.
176  *\param data_lengths One value for each entity specifying the
177  * length of the tag value for the corresponding
178  * entity. Array is required for variable-length
179  * tags and is ignored for fixed-length tags.
180  */
181  virtual ErrorCode set_data( SequenceManager* seqman,
182  Error* error_handler,
183  const Range& entities,
184  void const* const* data_ptrs,
185  const int* data_lengths );
186 
187  /**\brief Set tag value for passed entities
188  *
189  * Store tag data or update stored tag values.
190  *
191  *\param seqman Pointer to mesh entity database
192  *\param entities Entity handles for which to store tag data
193  *\param num_entities Length of \c entities array
194  *\param value_ptr Pointer to a single tag value which is to be
195  * stored for each of the passed entities.
196  *\param value_len Length of tag value in bytes. Ignored for
197  * fixed-length tags. Required for variable-
198  * length tags.
199  */
200  virtual ErrorCode clear_data( SequenceManager* seqman,
201  Error* error_handler,
202  const EntityHandle* entities,
203  size_t num_entities,
204  const void* value_ptr,
205  int value_len = 0 );
206 
207  /**\brief Set tag value for passed entities
208  *
209  * Store tag data or update stored tag values.
210  *
211  *\param seqman Pointer to mesh entity database
212  *\param entities Entity handles for which to store tag data
213  *\param value_ptr Pointer to a single tag value which is to be
214  * stored for each of the passed entities.
215  *\param value_len Length of tag value in bytes. Ignored for
216  * fixed-length tags. Required for variable-
217  * length tags.
218  */
219  virtual ErrorCode clear_data( SequenceManager* seqman,
220  Error* error_handler,
221  const Range& entities,
222  const void* value_ptr,
223  int value_len = 0 );
224 
225  /**\brief Remove/clear tag data for entities
226  *
227  * Remove tag values from entities.
228  *
229  *\param seqman Pointer to mesh entity database
230  *\param entities Entity handles for which to store tag data
231  *\param num_entities Length of \c entities array
232  */
233  virtual ErrorCode remove_data( SequenceManager* seqman,
234  Error* error_handler,
235  const EntityHandle* entities,
236  size_t num_entities );
237 
238  /**\brief Remove/clear tag data for entities
239  *
240  * Remove tag values from entities.
241  *
242  *\param seqman Pointer to mesh entity database
243  *\param entities Entity handles for which to store tag data
244  */
245  virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const Range& entities );
246 
247  /**\brief Access tag data via direct pointer into contiguous blocks
248  *
249  * Iteratively obtain direct access to contiguous blocks of tag
250  * storage. This function cannot be used with bit tags because
251  * of the compressed bit storage. This function cannot be used
252  * with variable length tags because it does not provide a mechanism
253  * to determine the length of the value for each entity. This
254  * function may be used with sparse tags, but if it is used, it
255  * will return data for a single entity at a time.
256  *
257  *\param iter As input, the first entity for which to return
258  * data. As output, one past the last entity for
259  * which data was returned.
260  *\param end One past the last entity for which data is desired
261  *\param data_ptr Output: pointer to tag storage.
262  *
263  *\Note If this function is called for entities for which no tag value
264  * has been set, but for which a default value exists, it will
265  * force the allocation of explicit storage for each such entity
266  * even though MOAB would normally not explicitly store tag values
267  * for such entities.
268  */
269  virtual ErrorCode tag_iterate( SequenceManager* seqman,
270  Error* error_handler,
271  Range::iterator& iter,
272  const Range::iterator& end,
273  void*& data_ptr,
274  bool allocate = true );
275 
276  /**\brief Get all tagged entities
277  *
278  * Get the list of entities for which the a tag value has been set,
279  * or a close approximation if the tag storage scheme cannot
280  * accurately determine exactly which entities have explicit values.
281  *
282  *\param seqman Pointer to entity storage database
283  *\param output_entities Results *appended* to this range
284  *\param type Optional entity type. If specified, search is
285  * limited to entities of specified type.
286  *\param intersect Optional intersect list. If specified,
287  * search is restricted to entities in this list.
288  */
289  virtual ErrorCode get_tagged_entities( const SequenceManager* seqman,
290  Range& output_entities,
291  EntityType type = MBMAXTYPE,
292  const Range* intersect = 0 ) const;
293 
294  /**\brief Count all tagged entities
295  *
296  * Count the entities for which the a tag value has been set,
297  * or a close approximation if the tag storage scheme cannot
298  * accurately determine exactly which entities have explicit values.
299  *
300  *\param seqman Pointer to entity storage database
301  *\param output_count This is *incremented* for each detected entity.
302  *\param type Optional entity type. If specified, search is
303  * limited to entities of specified type.
304  *\param intersect Optional intersect list. If specified,
305  * search is restricted to entities in this list.
306  */
307  virtual ErrorCode num_tagged_entities( const SequenceManager* seqman,
308  size_t& output_count,
309  EntityType type = MBMAXTYPE,
310  const Range* intersect = 0 ) const;
311 
312  /**\brief Get all tagged entities with tag value
313  *
314  * Get the list of entities which have the specified tag value.
315  *
316  *\param seqman Pointer to entity storage database
317  *\param output_entities Results *appended* to this range
318  *\param value Pointer to tag value
319  *\param value_bytes Size of tag value in bytes.
320  *\param type Optional entity type. If specified, search is
321  * limited to entities of specified type.
322  *\param intersect_entities Optional intersect list. If specified,
323  * search is restricted to entities in this list.
324  */
325  virtual ErrorCode find_entities_with_value( const SequenceManager* seqman,
326  Error* error_handler,
327  Range& output_entities,
328  const void* value,
329  int value_bytes = 0,
330  EntityType type = MBMAXTYPE,
331  const Range* intersect_entities = 0 ) const;
332 
333  /**\brief Check if entity is tagged */
334  virtual bool is_tagged( const SequenceManager*, EntityHandle h ) const;
335 
336  /**\brief Get memory use for tag data.
337  *
338  */
339  ErrorCode get_memory_use( const SequenceManager* seqman, unsigned long& total, unsigned long& per_entity ) const;
340 
341  /**\brief Get entities for which an explicit tag of the specified value is stored */
342  ErrorCode get_entities_with_bits( EntityType type, Range& entities, unsigned char bits ) const;
343 
344  /**\brief Get entities for which an explicit tag of the specified value is stored */
345  ErrorCode get_entities_with_bits( const Range& range, EntityType type, Range& entities, unsigned char bits ) const;
346 
347  enum
348  {
349  Ln2PageSize = 12, //!< Constant: log2(PageSize)
350  PageSize = ( 1u << Ln2PageSize ) //!< Constant: Bytes per BitPage (power of 2)
351  };
352 
353  private:
354  BitTag( const BitTag& );
355  BitTag& operator=( const BitTag& );
356  ErrorCode reserve( unsigned bits );
357 
358  inline unsigned char default_val() const
359  {
360  if( get_default_value() )
361  return *reinterpret_cast< const unsigned char* >( get_default_value() );
362  else
363  return 0;
364  }
365 
366  std::vector< BitPage* > pageList[MBMAXTYPE]; //!< Array of BitPage instances storing actual data.
367  unsigned int requestedBitsPerEntity; //!< user-requested bits per entity
368  unsigned int storedBitsPerEntity; //!< allocated bits per entity (power of 2)
369  unsigned int pageShift; //!< log2( ents_per_page() )
370 
371  /**\brief Get indices from handle
372  *
373  *\param type Output: entity type
374  *\param page Output: index into pageList[type]
375  *\param offset Output: index into pageList[type][page]
376  */
377  void unpack( EntityHandle h, EntityType& type, size_t& page, int& offset ) const
378  {
379  type = TYPE_FROM_HANDLE( h );
380  h = ID_FROM_HANDLE( h );
381  page = ( (size_t)h ) >> pageShift; // h / ents_per_page()
382  offset = h & ( ( 1u << pageShift ) - 1u ); // h % ends_per_page()
383  }
384 
385  /**\brief Get the number of tag values that are stored in each BitPage */
386  int ents_per_page() const
387  {
388  return 8 * PageSize / storedBitsPerEntity;
389  }
390 
391  template < class Container >
392  inline void get_tagged( EntityType type, Container& entities ) const;
393  template < class Container >
394  inline void get_tagged( Range::const_iterator begin, Range::const_iterator end, Container& entities ) const;
395  template < class Container >
396  inline void get_tagged( Container& entities, EntityType type, const Range* intersect ) const;
397 };
398 
399 } // namespace moab
400 
401 #endif