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 
17 #ifndef VAR_LEN_SPARSE_TAG_HPP
18 #define VAR_LEN_SPARSE_TAG_HPP
19 
20 #ifndef IS_BUILDING_MB
21 #error "VarLenSparseTag.hpp isn't supposed to be included into an application"
22 #endif
23 
24 #ifdef WIN32
25 #pragma warning(disable : 4786)
26 #endif
27 
28 #include "moab/MOABConfig.h"
29 #define STRINGIFY_(X) #X
30 #define STRINGIFY(X) STRINGIFY_(X)
31 #ifdef MOAB_HAVE_UNORDERED_MAP
32 # include STRINGIFY(MOAB_HAVE_UNORDERED_MAP)
33 #else
34 # include <map>
35 #endif
36 #include <vector>
37 
38 #include "TagInfo.hpp"
39 #include "VarLenTag.hpp"
40 #include <stdlib.h>
41 
42 namespace moab {
43 
44 //! Sparse tag variable-length data
45 class VarLenSparseTag : public TagInfo
46 {
47 public:
48 
49   VarLenSparseTag( const char* name,
50                    DataType type,
51                    const void* default_value,
52                    int default_value_bytes );
53 
54   ~VarLenSparseTag();
55 
56   virtual TagType get_storage_type() const;
57 
58   /**\brief Remove/clear tag data for all entities
59    *
60    * Remove tag values from entities.
61    *
62    *\param delete_pending  If true, then release any global
63    *          data associated with the tag in preparation for deleting
64    *          the tag itself.
65    *
66    *\Note Invalidates tag if \c tag_delete_pending is true.  The only
67    *        valid method that can be invoked that is is the destructor.
68    *
69    *\param seqman    Pointer to mesh entity database
70    */
71   virtual ErrorCode release_all_data( SequenceManager* seqman,
72                                       Error* error_handler,
73                                       bool delete_pending );
74 
75 
76   /**\brief Get tag value for passed entities
77    *
78    * Get tag values for specified entities.
79    *
80    *\Note Will fail for variable-length data.
81    *\param seqman Pointer to mesh entity database
82    *\param entities Entity handles for which to retrieve tag data
83    *\param num_entities Length of \c entities array
84    *\param data Pointer to memory in which to store consecutive tag values,
85    *            one for each passed entity.
86    */
87   virtual
88   ErrorCode get_data( const SequenceManager* seqman,
89                       Error* error_handler,
90                       const EntityHandle* entities,
91                       size_t num_entities,
92                       void* data ) const;
93 
94   /**\brief Get tag value for passed entities
95    *
96    * Get tag values for specified entities.
97    *
98    *\Note Will fail for variable-length data.
99    *\param seqman Pointer to mesh entity database
100    *\param entities Entity handles for which to retrieve tag data
101    *\param data Pointer to memory in which to store consecutive tag values,
102    *            one for each passed entity.
103    */
104   virtual
105   ErrorCode get_data( const SequenceManager* seqman,
106                       Error* error_handler,
107                       const Range& entities,
108                       void* data ) const;
109 
110   /**\brief Get tag value for passed entities
111    *
112    * Get tag values for specified entities.
113    *
114    *\param seqman    Pointer to mesh entity database
115    *\param entities  Entity handles for which to retrieve tag data
116    *\param num_entities Length of \c entities array
117    *\param data_ptrs Array of pointers to tag values, one pointer
118    *                 for each passed entity.
119    *\param data_lengths One value for each entity specifying the
120    *                length of the tag value for the corresponding
121    *                entity.
122    */
123   virtual
124   ErrorCode get_data( const SequenceManager* seqman,
125                       Error* error_handler,
126                       const EntityHandle* entities,
127                       size_t num_entities,
128                       const void** data_ptrs,
129                       int* data_lengths ) const ;
130 
131 
132   /**\brief Get tag value for passed entities
133    *
134    * Get tag values for specified entities.
135    *
136    *\param seqman    Pointer to mesh entity database
137    *\param entities  Entity handles for which to retrieve tag data
138    *\param data_ptrs Array of pointers to tag values, one pointer
139    *                 for each passed entity.
140    *\param data_lengths One value for each entity specifying the
141    *                length of the tag value for the corresponding
142    *                entity.
143    */
144   virtual
145   ErrorCode get_data( const SequenceManager* seqman,
146                       Error* error_handler,
147                       const Range& entities,
148                       const void** data_ptrs,
149                       int* data_lengths ) const;
150 
151   /**\brief Set tag value for passed entities
152    *
153    * Store tag data or update stored tag values
154    *\Note Will fail for variable-length data.
155    *\param seqman Pointer to mesh entity database
156    *\param entities Entity handles for which to store tag data
157    *\param num_entities Length of \c entities array
158    *\param data Pointer to memory holding consecutive tag values,
159    *            one for each passed entity.
160    */
161   virtual
162   ErrorCode set_data( SequenceManager* seqman,
163                       Error* error_handler,
164                       const EntityHandle* entities,
165                       size_t num_entities,
166                       const void* data );
167 
168   /**\brief Set tag value for passed entities
169    *
170    * Store tag data or update stored tag values
171    *\Note Will fail for variable-length data.
172    *\param seqman Pointer to mesh entity database
173    *\param entities Entity handles for which to store tag data
174    *\param data Pointer to memory holding consecutive tag values,
175    *            one for each passed entity.
176    */
177   virtual
178   ErrorCode set_data( SequenceManager* seqman,
179                       Error* error_handler,
180                       const Range& entities,
181                       const void* data );
182 
183   /**\brief Set tag value for passed entities
184    *
185    * Store tag data or update stored tag values
186    *
187    *\param seqman    Pointer to mesh entity database
188    *\param entities  Entity handles for which to store tag data
189    *\param num_entities Length of \c entities array
190    *\param data_ptrs Array of pointers to tag values, one pointer
191    *                 for each passed entity.
192    *\param data_lengths One value for each entity specifying the
193    *                length of the tag value for the corresponding
194    *                entity.  Array is required for variable-length
195    *                tags and is ignored for fixed-length tags.
196    */
197   virtual
198   ErrorCode set_data( SequenceManager* seqman,
199                       Error* error_handler,
200                       const EntityHandle* entities,
201                       size_t num_entities,
202                       void const* const* data_ptrs,
203                       const int* data_lengths );
204 
205 
206   /**\brief Set tag value for passed entities
207    *
208    * Store tag data or update stored tag values
209    *
210    *\param seqman    Pointer to mesh entity database
211    *\param entities  Entity handles for which to store tag data
212    *\param data_ptrs Array of pointers to tag values, one pointer
213    *                 for each passed entity.
214    *\param data_lengths One value for each entity specifying the
215    *                length of the tag value for the corresponding
216    *                entity.  Array is required for variable-length
217    *                tags and is ignored for fixed-length tags.
218    */
219   virtual
220   ErrorCode set_data( SequenceManager* seqman,
221                       Error* error_handler,
222                       const Range& entities,
223                       void const* const* data_ptrs,
224                       const int* data_lengths );
225 
226   /**\brief Set tag value for passed entities
227    *
228    * Store tag data or update stored tag values.
229    *
230    *\param seqman    Pointer to mesh entity database
231    *\param entities  Entity handles for which to store tag data
232    *\param num_entities Length of \c entities array
233    *\param value_ptr Pointer to a single tag value which is to be
234    *                 stored for each of the passed entities.
235    *\param value_len Length of tag value in bytes.  Ignored for
236    *                 fixed-length tags.  Required for variable-
237    *                 length tags.
238    */
239   virtual
240   ErrorCode clear_data( SequenceManager* seqman,
241                         Error* error_handler,
242                         const EntityHandle* entities,
243                         size_t num_entities,
244                         const void* value_ptr,
245                         int value_len = 0 );
246 
247   /**\brief Set tag value for passed entities
248    *
249    * Store tag data or update stored tag values.
250    *
251    *\param seqman    Pointer to mesh entity database
252    *\param entities  Entity handles for which to store tag data
253    *\param value_ptr Pointer to a single tag value which is to be
254    *                 stored for each of the passed entities.
255    *\param value_len Length of tag value in bytes.  Ignored for
256    *                 fixed-length tags.  Required for variable-
257    *                 length tags.
258    */
259   virtual
260   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,
287                                  Error* error_handler,
288                                  const Range& entities );
289 
290   /**\brief Access tag data via direct pointer into contiguous blocks
291    *
292    * Iteratively obtain direct access to contiguous blocks of tag
293    * storage.  This function cannot be used with bit tags because
294    * of the compressed bit storage.  This function cannot be used
295    * with variable length tags because it does not provide a mechanism
296    * to determine the length of the value for each entity.  This
297    * function may be used with sparse tags, but if it is used, it
298    * will return data for a single entity at a time.
299    *
300    *\param iter        As input, the first entity for which to return
301    *                   data.  As output, one past the last entity for
302    *                   which data was returned.
303    *\param end         One past the last entity for which data is desired
304    *\param data_ptr    Output: pointer to tag storage.
305    *
306    *\Note If this function is called for entities for which no tag value
307    *      has been set, but for which a default value exists, it will
308    *      force the allocation of explicit storage for each such entity
309    *      even though MOAB would normally not explicitly store tag values
310    *      for such entities.
311    */
312   virtual
313   ErrorCode tag_iterate( SequenceManager* seqman,
314                          Error* error_handler,
315                          Range::iterator& iter,
316                          const Range::iterator& end,
317                          void*& data_ptr,
318                          bool allocate = true);
319 
320   /**\brief Get all tagged entities
321    *
322    * Get the list of entities for which the a tag value has been set,
323    * or a close approximation if the tag storage scheme cannot
324    * accurately determine exactly which entities have explicit values.
325    *
326    *\param seqman   Pointer to entity storage database
327    *\param output_entities Results *appended* to this range
328    *\param type     Optional entity type.  If specified, search is
329    *                limited to entities of specified type.
330    *\param intersect Optional intersect list.  If specified,
331    *                search is restricted to entities in this list.
332    */
333   virtual
334   ErrorCode get_tagged_entities( const SequenceManager* seqman,
335                                  Range& output_entities,
336                                  EntityType type = MBMAXTYPE,
337                                  const Range* intersect = 0 ) const;
338 
339   /**\brief Count all tagged entities
340    *
341    * Count the entities for which the a tag value has been set,
342    * or a close approximation if the tag storage scheme cannot
343    * accurately determine exactly which entities have explicit values.
344    *
345    *\param seqman   Pointer to entity storage database
346    *\param output_count This is *incremented* for each detected entity.
347    *\param type     Optional entity type.  If specified, search is
348    *                limited to entities of specified type.
349    *\param intersect Optional intersect list.  If specified,
350    *                search is restricted to entities in this list.
351    */
352   virtual
353   ErrorCode num_tagged_entities( const SequenceManager* seqman,
354                                  size_t& output_count,
355                                  EntityType type = MBMAXTYPE,
356                                  const Range* intersect = 0 ) const;
357 
358   /**\brief Get all tagged entities with tag value
359    *
360    * Get the list of entities which have the specified tag value.
361    *
362    *\param seqman   Pointer to entity storage database
363    *\param output_entities Results *appended* to this range
364    *\param value    Pointer to tag value
365    *\param value_bytes Size of tag value in bytes.
366    *\param type     Optional entity type.  If specified, search is
367    *                limited to entities of specified type.
368    *\param intersect_entities Optional intersect list.  If specified,
369    *                search is restricted to entities in this list.
370    */
371   virtual
372   ErrorCode find_entities_with_value( const SequenceManager* seqman,
373                                       Error* error_handler,
374                                       Range& output_entities,
375                                       const void* value,
376                                       int value_bytes = 0,
377                                       EntityType type = MBMAXTYPE,
378                                       const Range* intersect_entities = 0 ) const;
379 
380   /**\brief Check if entity is tagged */
381   virtual bool is_tagged( const SequenceManager*, EntityHandle h ) const;
382 
383   /**\brief Get memory use for tag data.
384    *
385    */
386   virtual
387   ErrorCode get_memory_use( const SequenceManager* seqman,
388                             unsigned long& total,
389                             unsigned long& per_entity ) const;
390 
391   //! get number of entities
get_number_entities()392   unsigned long get_number_entities()
393     { return mData.size(); }
394 
395 
396   //! map of entity id and tag data
397 #ifdef MOAB_HAVE_UNORDERED_MAP
398   typedef MOAB_UNORDERED_MAP_NS::unordered_map<EntityHandle,VarLenTag> MapType;
399 #else
400   typedef std::map<EntityHandle,VarLenTag> MapType;
401 #endif
402 
403 private:
404 
405   VarLenSparseTag( const VarLenSparseTag& );
406   VarLenSparseTag& operator=( const VarLenSparseTag& );
407 
408   //! get the variable-length data for an entity id
409   inline
410   ErrorCode get_data_ptr( Error* error_handler,
411                           EntityHandle entity_handle,
412                           const void*& data,
413                           int& size) const;
414 
415   MapType mData;
416 };
417 
418 } // namespace moab
419 
420 #endif // VAR_LEN_SPARSE_TAG_HPP
421 
422 
423 
424 
425