Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
SparseTag.hpp
Go to the documentation of this file.
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 <cstdlib>
39 
40 namespace moab
41 {
42 
43 //! allocator for tag data
45 {
46  public:
47  //! constructor
49  //! destructor
51  //! allocates memory of size and returns pointer
52  void* allocate( size_t data_size )
53  {
54  return malloc( data_size );
55  }
56  //! frees the memory
57  void destroy( void* p )
58  {
59  free( p );
60  }
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,
100  Error* error_handler,
101  const EntityHandle* entities,
102  size_t num_entities,
103  void* data ) const;
104 
105  /**\brief Get tag value for passed entities
106  *
107  * Get tag values for specified entities.
108  *
109  *\Note Will fail for variable-length data.
110  *\param seqman Pointer to mesh entity database
111  *\param entities Entity handles for which to retrieve tag data
112  *\param data Pointer to memory in which to store consecutive tag values,
113  * one for each passed entity.
114  */
115  virtual ErrorCode get_data( const SequenceManager* seqman,
116  Error* error_handler,
117  const Range& entities,
118  void* data ) const;
119 
120  /**\brief Get tag value for passed entities
121  *
122  * Get tag values for specified entities.
123  *
124  *\param seqman Pointer to mesh entity database
125  *\param entities Entity handles for which to retrieve tag data
126  *\param num_entities Length of \c entities array
127  *\param data_ptrs Array of pointers to tag values, one pointer
128  * for each passed entity.
129  *\param data_lengths One value for each entity specifying the
130  * length of the tag value for the corresponding
131  * entity.
132  */
133  virtual ErrorCode get_data( const SequenceManager* seqman,
134  Error* error_handler,
135  const EntityHandle* entities,
136  size_t num_entities,
137  const void** data_ptrs,
138  int* data_lengths ) const;
139 
140  /**\brief Get tag value for passed entities
141  *
142  * Get tag values for specified entities.
143  *
144  *\param seqman Pointer to mesh entity database
145  *\param entities Entity handles for which to retrieve tag data
146  *\param data_ptrs Array of pointers to tag values, one pointer
147  * for each passed entity.
148  *\param data_lengths One value for each entity specifying the
149  * length of the tag value for the corresponding
150  * entity.
151  */
152  virtual ErrorCode get_data( const SequenceManager* seqman,
153  Error* error_handler,
154  const Range& entities,
155  const void** data_ptrs,
156  int* data_lengths ) const;
157 
158  /**\brief Set tag value for passed entities
159  *
160  * Store tag data or update stored tag values
161  *\Note Will fail for variable-length data.
162  *\param seqman Pointer to mesh entity database
163  *\param entities Entity handles for which to store tag data
164  *\param num_entities Length of \c entities array
165  *\param data Pointer to memory holding consecutive tag values,
166  * one for each passed entity.
167  */
168  virtual ErrorCode set_data( SequenceManager* seqman,
169  Error* error_handler,
170  const EntityHandle* entities,
171  size_t num_entities,
172  const void* data );
173 
174  /**\brief Set tag value for passed entities
175  *
176  * Store tag data or update stored tag values
177  *\Note Will fail for variable-length data.
178  *\param seqman Pointer to mesh entity database
179  *\param entities Entity handles for which to store tag data
180  *\param data Pointer to memory holding consecutive tag values,
181  * one for each passed entity.
182  */
183  virtual ErrorCode set_data( SequenceManager* seqman,
184  Error* error_handler,
185  const Range& entities,
186  const void* data );
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 num_entities Length of \c entities array
195  *\param data_ptrs Array of pointers to tag values, one pointer
196  * for each passed entity.
197  *\param data_lengths One value for each entity specifying the
198  * length of the tag value for the corresponding
199  * entity. Array is required for variable-length
200  * tags and is ignored for fixed-length tags.
201  */
202  virtual ErrorCode set_data( SequenceManager* seqman,
203  Error* error_handler,
204  const EntityHandle* entities,
205  size_t num_entities,
206  void const* const* data_ptrs,
207  const int* data_lengths );
208 
209  /**\brief Set tag value for passed entities
210  *
211  * Store tag data or update stored tag values
212  *
213  *\param seqman Pointer to mesh entity database
214  *\param entities Entity handles for which to store tag data
215  *\param data_ptrs Array of pointers to tag values, one pointer
216  * for each passed entity.
217  *\param data_lengths One value for each entity specifying the
218  * length of the tag value for the corresponding
219  * entity. Array is required for variable-length
220  * tags and is ignored for fixed-length tags.
221  */
222  virtual ErrorCode set_data( SequenceManager* seqman,
223  Error* error_handler,
224  const Range& entities,
225  void const* const* data_ptrs,
226  const int* data_lengths );
227 
228  /**\brief Set tag value for passed entities
229  *
230  * Store tag data or update stored tag values.
231  *
232  *\param seqman Pointer to mesh entity database
233  *\param entities Entity handles for which to store tag data
234  *\param num_entities Length of \c entities array
235  *\param value_ptr Pointer to a single tag value which is to be
236  * stored for each of the passed entities.
237  *\param value_len Length of tag value in bytes. Ignored for
238  * fixed-length tags. Required for variable-
239  * length tags.
240  */
241  virtual ErrorCode clear_data( SequenceManager* seqman,
242  Error* error_handler,
243  const EntityHandle* entities,
244  size_t num_entities,
245  const void* value_ptr,
246  int value_len = 0 );
247 
248  /**\brief Set tag value for passed entities
249  *
250  * Store tag data or update stored tag values.
251  *
252  *\param seqman Pointer to mesh entity database
253  *\param entities Entity handles for which to store tag data
254  *\param value_ptr Pointer to a single tag value which is to be
255  * stored for each of the passed entities.
256  *\param value_len Length of tag value in bytes. Ignored for
257  * fixed-length tags. Required for variable-
258  * length tags.
259  */
260  virtual ErrorCode clear_data( SequenceManager* seqman,
261  Error* error_handler,
262  const Range& entities,
263  const void* value_ptr,
264  int value_len = 0 );
265 
266  /**\brief Remove/clear tag data for entities
267  *
268  * Remove tag values from entities.
269  *
270  *\param seqman Pointer to mesh entity database
271  *\param entities Entity handles for which to store tag data
272  *\param num_entities Length of \c entities array
273  */
274  virtual ErrorCode remove_data( SequenceManager* seqman,
275  Error* error_handler,
276  const EntityHandle* entities,
277  size_t num_entities );
278 
279  /**\brief Remove/clear tag data for entities
280  *
281  * Remove tag values from entities.
282  *
283  *\param seqman Pointer to mesh entity database
284  *\param entities Entity handles for which to store tag data
285  */
286  virtual ErrorCode remove_data( SequenceManager* seqman, Error* error_handler, const Range& entities );
287 
288  /**\brief Access tag data via direct pointer into contiguous blocks
289  *
290  * Iteratively obtain direct access to contiguous blocks of tag
291  * storage. This function cannot be used with bit tags because
292  * of the compressed bit storage. This function cannot be used
293  * with variable length tags because it does not provide a mechanism
294  * to determine the length of the value for each entity. This
295  * function may be used with sparse tags, but if it is used, it
296  * will return data for a single entity at a time.
297  *
298  *\param iter As input, the first entity for which to return
299  * data. As output, one past the last entity for
300  * which data was returned.
301  *\param end One past the last entity for which data is desired
302  *\param data_ptr Output: pointer to tag storage.
303  *\param allocate If true, space for this tag will be allocated, if not it wont
304  *
305  *\Note If this function is called for entities for which no tag value
306  * has been set, but for which a default value exists, it will
307  * force the allocation of explicit storage for each such entity
308  * even though MOAB would normally not explicitly store tag values
309  * for such entities.
310  */
311  virtual ErrorCode tag_iterate( SequenceManager* seqman,
312  Error* error_handler,
313  Range::iterator& iter,
314  const Range::iterator& end,
315  void*& data_ptr,
316  bool allocate = true );
317 
318  /**\brief Get all tagged entities
319  *
320  * Get the list of entities for which the a tag value has been set,
321  * or a close approximation if the tag storage scheme cannot
322  * accurately determine exactly which entities have explicit values.
323  *
324  *\param seqman Pointer to entity storage database
325  *\param output_entities Results *appended* to this range
326  *\param type Optional entity type. If specified, search is
327  * limited to entities of specified type.
328  *\param intersect Optional intersect list. If specified,
329  * search is restricted to entities in this list.
330  */
331  virtual ErrorCode get_tagged_entities( const SequenceManager* seqman,
332  Range& output_entities,
333  EntityType type = MBMAXTYPE,
334  const Range* intersect = 0 ) const;
335 
336  /**\brief Count all tagged entities
337  *
338  * Count the entities for which the a tag value has been set,
339  * or a close approximation if the tag storage scheme cannot
340  * accurately determine exactly which entities have explicit values.
341  *
342  *\param seqman Pointer to entity storage database
343  *\param output_count This is *incremented* for each detected entity.
344  *\param type Optional entity type. If specified, search is
345  * limited to entities of specified type.
346  *\param intersect Optional intersect list. If specified,
347  * search is restricted to entities in this list.
348  */
349  virtual ErrorCode num_tagged_entities( const SequenceManager* seqman,
350  size_t& output_count,
351  EntityType type = MBMAXTYPE,
352  const Range* intersect = 0 ) const;
353 
354  /**\brief Get all tagged entities with tag value
355  *
356  * Get the list of entities which have the specified tag value.
357  *
358  *\param seqman Pointer to entity storage database
359  *\param output_entities Results *appended* to this range
360  *\param value Pointer to tag value
361  *\param value_bytes Size of tag value in bytes.
362  *\param type Optional entity type. If specified, search is
363  * limited to entities of specified type.
364  *\param intersect_entities Optional intersect list. If specified,
365  * search is restricted to entities in this list.
366  */
367  virtual ErrorCode find_entities_with_value( const SequenceManager* seqman,
368  Error* error_handler,
369  Range& output_entities,
370  const void* value,
371  int value_bytes = 0,
372  EntityType type = MBMAXTYPE,
373  const Range* intersect_entities = 0 ) const;
374 
375  /**\brief Check if entity is tagged */
376  virtual bool is_tagged( const SequenceManager*, EntityHandle h ) const;
377 
378  /**\brief Get memory use for tag data.
379  *
380  */
381  virtual ErrorCode get_memory_use( const SequenceManager* seqman,
382  unsigned long& total,
383  unsigned long& per_entity ) const;
384 
385  //! get number of entities
386  unsigned long get_number_entities()
387  {
388  return mData.size();
389  }
390 
391  //! map of entity id and tag data
392 #ifdef MOAB_HAVE_UNORDERED_MAP
393  typedef MOAB_UNORDERED_MAP_NS::unordered_map< EntityHandle, void* > MapType;
394 #else
395  typedef std::map< EntityHandle, void* > MapType;
396 #endif
397 
398  private:
399  SparseTag( const SparseTag& );
401 
402  //! allocate an entry for this sparse tag w/o setting its value (yet)
403  inline void* allocate_data( EntityHandle h, MapType::const_iterator iter, bool copy_default = true );
404 
405  //! set the tag data for an entity id
406  //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for
407  //! variable-length tag.
408  inline ErrorCode set_data( Error*, EntityHandle entity_handle, const void* data );
409 
410  //! get the tag data for an entity id
411  //!\NOTE Will fail with MB_VARIABLE_DATA_LENGTH if called for
412  //! variable-length tag.
413  inline ErrorCode get_data( Error*, EntityHandle entity_handle, void* data ) const;
414 
415  //! get the variable-length data for an entity id
416  inline ErrorCode get_data_ptr( EntityHandle entity_handle, const void*& data, bool allocate = true ) const;
417 
418  //! removes the data
419  inline ErrorCode remove_data( Error*, EntityHandle entity_handle );
420 
421  //! allocator for this collection
423 
425 };
426 
429  MapType::const_iterator iter,
430 #else
431  MapType::const_iterator,
432 #endif
433  bool copy_default )
434 {
435  void* new_data = mAllocator.allocate( get_size() );
436 #ifdef MOAB_HAVE_UNORDERED_MAP
437  mData.insert( iter, std::pair< const EntityHandle, void* >( h, new_data ) );
438 #else
439  mData[h] = new_data;
440 #endif
441  if( copy_default ) memcpy( new_data, get_default_value(), get_size() );
442  return new_data;
443 }
444 
445 } // namespace moab
446 
447 #endif // SPARSE_TAG_HPP