1 #ifndef SEQUENCE_DATA_HPP
2 #define SEQUENCE_DATA_HPP
3 
4 
5 #include "TypeSequenceManager.hpp"
6 
7 #include <vector>
8 #include <stdlib.h>
9 #include <string.h>
10 
11 namespace moab {
12 
13 class SequenceData
14 {
15 public:
16 
17   typedef std::vector<EntityHandle>* AdjacencyDataType;
18 
19   /**\param num_sequence_arrays Number of data arrays needed by the EntitySequence
20    * \param start               First handle in this SequenceData
21    * \param end                 Last handle in this SequenceData
22    */
23   inline SequenceData( int num_sequence_arrays,
24                        EntityHandle start,
25                        EntityHandle end );
26 
27   virtual ~SequenceData();
28 
29   /**\return first handle in this sequence data */
start_handle() const30   EntityHandle start_handle() const
31     { return startHandle; }
32 
33   /**\return last handle in this sequence data */
end_handle() const34   EntityHandle end_handle() const
35     { return endHandle; }
36 
size() const37   EntityID size() const
38     { return endHandle + 1 - startHandle; }
39 
40   /**\return ith array of EnitySequence-specific data */
get_sequence_data(int array_num)41   void*       get_sequence_data( int array_num )
42                 { return arraySet[-1-array_num]; }
43   /**\return ith array of EnitySequence-specific data */
get_sequence_data(int array_num) const44   void const* get_sequence_data( int array_num ) const
45                 { return arraySet[-1-array_num]; }
46 
47   /**\return array of adjacency data, or NULL if none. */
get_adjacency_data()48   AdjacencyDataType*       get_adjacency_data( )
49                 { return reinterpret_cast<AdjacencyDataType*>(arraySet[0]); }
50   /**\return array of adjacency data, or NULL if none. */
get_adjacency_data() const51   AdjacencyDataType const* get_adjacency_data( ) const
52                 { return reinterpret_cast<AdjacencyDataType const*>(arraySet[0]); }
53 
54   /**\return array of dense tag data, or NULL if none. */
get_tag_data(unsigned tag_num)55   void*       get_tag_data( unsigned tag_num )
56                 { return tag_num < numTagData  ? arraySet[tag_num+1] : 0; }
57   /**\return array of dense tag data, or NULL if none. */
get_tag_data(unsigned tag_num) const58   void const* get_tag_data( unsigned tag_num ) const
59                 { return tag_num < numTagData  ? arraySet[tag_num+1] : 0; }
60 
61   /**\brief Allocate array of sequence-specific data
62    *
63    * Allocate an array of EntitySequence-specific data.
64    *\param array_num Index for which to allocate array.
65    *                 Must be in [0,num_sequence_arrays], where
66    *                 num_sequence_arrays is constructor argument.
67    *\param bytes_per_ent  Bytes to allocate for each entity.
68    *\param initial_val Value to initialize array with.  If non-null, must
69    *                   be bytes_per_ent long.  If NULL, array will be zeroed.
70    *\return The newly allocated array, or NULL if error.
71    */
72   void* create_sequence_data( int array_num,
73                               int bytes_per_ent,
74                               const void* initial_val = 0 );
75 
76   /**\brief Allocate array of sequence-specific data
77    *
78    * Allocate an array of EntitySequence-specific data.
79    *\param array_num Index for which to allocate array.
80    *                 Must be in [0,num_sequence_arrays], where
81    *                 num_sequence_arrays is constructor argument.
82    *\return The newly allocated array, or NULL if error.
83    */
84   void* create_custom_data( int array_num, size_t total_bytes );
85 
86   /**\brief Allocate array for storing adjacency data.
87    *
88    * Allocate array for storing adjacency data.
89    *\return The newly allocated array, or NULL if already allocated.
90    */
91   AdjacencyDataType* allocate_adjacency_data();
92 
93   /**\brief Allocate array of dense tag data
94    *
95    * Allocate an array of dense tag data.
96    *\param index        Dense tag ID for which to allocate array.
97    *\param bytes_per_ent  Bytes to allocate for each entity.
98    *\return The newly allocated array, or NULL if error.
99    */
100   void* allocate_tag_array( int index, int bytes_per_ent, const void* default_value = 0 );
101 
102   /**\brief Create new SequenceData that is a copy of a subset of this one
103     *
104     * Create a new SequenceData that is a copy of a subset of this one.
105     * This function is intended for use in subdividing a SequenceData
106     * for operations such as changing the number of nodes in a block of
107     * elements.
108     *\param start  First handle for resulting subset
109     *\param end    Last handle for resulting subset
110     *\param sequence_data_sizes Bytes-per-entity for sequence-specific data.
111     *\NOTE Does not copy tag data.
112     */
113   SequenceData* subset( EntityHandle start,
114                         EntityHandle end,
115                         const int* sequence_data_sizes ) const;
116 
117   /**\brief SequenceManager data */
118   TypeSequenceManager::SequenceDataPtr seqManData;
119 
120   /**\brief Move tag data for a subset of this sequences to specified sequence */
121   void move_tag_data( SequenceData* destination, const int* tag_sizes, int num_tag_sizes );
122 
123   /**\brief Free all tag data arrays */
124   void release_tag_data(const int* tag_sizes, int num_tag_sizes);
125   /**\brief Free specified tag data array */
126   void release_tag_data( int index, int tag_size );
127 
128 protected:
129 
130   SequenceData( const SequenceData* subset_from,
131                 EntityHandle start,
132                 EntityHandle end,
133                 const int* sequence_data_sizes );
134 
135 private:
136 
137   void increase_tag_count( unsigned by_this_many );
138 
139   void* create_data( int index, int bytes_per_ent, const void* initial_val = 0 );
140   void copy_data_subset( int index,
141                          int size_per_ent,
142                          const void* source,
143                          size_t offset,
144                          size_t count );
145 
146   const int numSequenceData;
147   unsigned numTagData;
148   void** arraySet;
149   EntityHandle startHandle, endHandle;
150 };
151 
SequenceData(int num_sequence_arrays,EntityHandle start,EntityHandle end)152 inline SequenceData::SequenceData( int num_sequence_arrays,
153                                    EntityHandle start,
154                                    EntityHandle end )
155   : numSequenceData(num_sequence_arrays),
156     numTagData(0),
157     startHandle(start),
158     endHandle(end)
159 {
160   const size_t sz = sizeof(void*) * (num_sequence_arrays + 1);
161   void** data = (void**)malloc( sz );
162   memset( data, 0, sz );
163   arraySet = data + num_sequence_arrays;
164 }
165 
166 } // namespace moab
167 
168 #endif
169