Branch data Line data Source code
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 : : #include <memory.h>
17 : : #include <algorithm>
18 : :
19 : : #include "VarLenSparseTag.hpp"
20 : : #include "moab/Range.hpp"
21 : : #include "TagCompare.hpp"
22 : : #include "SequenceManager.hpp"
23 : : #include "moab/Error.hpp"
24 : : #include "moab/ErrorHandler.hpp"
25 : : #include "moab/CN.hpp"
26 : :
27 : : namespace moab
28 : : {
29 : :
30 : 98 : VarLenSparseTag::VarLenSparseTag( const char* name, DataType type, const void* default_value, int default_value_bytes )
31 [ + - ]: 98 : : TagInfo( name, MB_VARIABLE_LENGTH, type, default_value, default_value_bytes )
32 : : {
33 : 98 : }
34 : :
35 : 288 : VarLenSparseTag::~VarLenSparseTag()
36 : : {
37 : 96 : release_all_data( 0, 0, true );
38 [ - + ]: 192 : }
39 : :
40 : 31 : TagType VarLenSparseTag::get_storage_type() const
41 : : {
42 : 31 : return MB_TAG_SPARSE;
43 : : }
44 : :
45 : 234 : ErrorCode VarLenSparseTag::release_all_data( SequenceManager*, Error*, bool )
46 : : {
47 : 234 : mData.clear();
48 : 234 : return MB_SUCCESS;
49 : : }
50 : :
51 : 1118 : ErrorCode VarLenSparseTag::get_data_ptr( Error* /* error */, EntityHandle entity_handle, const void*& ptr,
52 : : int& length ) const
53 : : {
54 [ + - ]: 1118 : MapType::const_iterator iter = mData.find( entity_handle );
55 : :
56 [ + - ][ + + ]: 1118 : if( iter != mData.end() )
57 : : {
58 [ + - ][ + - ]: 911 : ptr = iter->second.data();
59 [ + - ][ + - ]: 911 : length = iter->second.size();
60 : : }
61 [ + - ][ + + ]: 207 : else if( get_default_value() )
62 : : {
63 [ + - ]: 38 : ptr = get_default_value();
64 [ + - ]: 38 : length = get_default_value_size();
65 : : }
66 : : else
67 : 169 : return MB_TAG_NOT_FOUND;
68 : :
69 : 1118 : return MB_SUCCESS;
70 : : }
71 : :
72 : 0 : ErrorCode VarLenSparseTag::get_data( const SequenceManager*, Error* /* error */, const EntityHandle*, size_t,
73 : : void* ) const
74 : : {
75 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
76 : : }
77 : :
78 : 0 : ErrorCode VarLenSparseTag::get_data( const SequenceManager*, Error* /* error */, const Range& /*entities*/,
79 : : void* /* data */ ) const
80 : : {
81 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
82 : : }
83 : :
84 : 632 : ErrorCode VarLenSparseTag::get_data( const SequenceManager*, Error* /* error */, const EntityHandle* entities,
85 : : size_t num_entities, const void** pointers, int* lengths ) const
86 : : {
87 [ - + ]: 632 : if( !lengths )
88 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
89 : :
90 : : ErrorCode rval;
91 [ + + ]: 1097 : for( size_t i = 0; i < num_entities; ++i )
92 : : {
93 : 632 : rval = get_data_ptr( NULL, entities[i], pointers[i], lengths[i] );
94 [ + + ]: 632 : if( rval != MB_SUCCESS ) return rval;
95 : : }
96 : :
97 : 632 : return MB_SUCCESS;
98 : : }
99 : :
100 : 59 : ErrorCode VarLenSparseTag::get_data( const SequenceManager*, Error* /* error */, const Range& entities,
101 : : const void** pointers, int* lengths ) const
102 : : {
103 [ - + ]: 59 : if( !lengths )
104 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
105 : :
106 : : ErrorCode rval;
107 [ + - ]: 59 : Range::const_iterator i;
108 [ + - ][ + - ]: 543 : for( i = entities.begin(); i != entities.end(); ++i, ++pointers, ++lengths )
[ + - ][ + - ]
[ + + ]
109 : : {
110 [ + - ][ + - ]: 486 : rval = get_data_ptr( NULL, *i, *pointers, *lengths );
111 [ + + ]: 486 : if( rval != MB_SUCCESS ) return rval;
112 : : }
113 : :
114 : 59 : return MB_SUCCESS;
115 : : }
116 : :
117 : 0 : ErrorCode VarLenSparseTag::set_data( SequenceManager* /* seqman */, Error* /* error */,
118 : : const EntityHandle* /* entities */, size_t /* num_entities */,
119 : : const void* /* data */ )
120 : : {
121 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
122 : : }
123 : :
124 : 0 : ErrorCode VarLenSparseTag::set_data( SequenceManager* /* seqman */, Error* /* error */, const Range& /* entities */,
125 : : const void* /* data */ )
126 : : {
127 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
128 : : }
129 : :
130 : 924 : ErrorCode VarLenSparseTag::set_data( SequenceManager* seqman, Error* /* error */, const EntityHandle* entities,
131 : : size_t num_entities, void const* const* pointers, const int* lengths )
132 : : {
133 [ - + ][ # # ]: 924 : ErrorCode rval = validate_lengths( NULL, lengths, num_entities );MB_CHK_ERR( rval );
134 : :
135 [ - + ][ # # ]: 924 : rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
136 : :
137 [ + + ]: 1848 : for( size_t i = 0; i < num_entities; ++i )
138 : : {
139 [ + - ]: 924 : if( lengths[i] )
140 : 924 : mData[entities[i]].set( pointers[i], lengths[i] );
141 : : else
142 : : {
143 [ # # ]: 0 : MapType::iterator iter = mData.find( entities[i] );
144 [ # # ][ # # ]: 0 : if( iter != mData.end() )
145 : : {
146 [ # # ][ # # ]: 0 : iter->second.clear();
147 [ # # ]: 0 : mData.erase( iter );
148 : : }
149 : : }
150 : : }
151 : :
152 : 924 : return MB_SUCCESS;
153 : : }
154 : :
155 : 2 : ErrorCode VarLenSparseTag::set_data( SequenceManager* seqman, Error* /* error */, const Range& entities,
156 : : void const* const* pointers, const int* lengths )
157 : : {
158 [ + - ][ + - ]: 2 : ErrorCode rval = validate_lengths( NULL, lengths, entities.size() );MB_CHK_ERR( rval );
[ - + ][ # # ]
[ # # ]
159 : :
160 [ + - ][ - + ]: 2 : rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
[ # # ][ # # ]
161 : :
162 [ + - ]: 2 : Range::const_iterator i;
163 [ + - ][ + - ]: 22 : for( i = entities.begin(); i != entities.end(); ++i, ++pointers, ++lengths )
[ + - ][ + - ]
[ + + ]
164 : : {
165 [ + - ]: 20 : if( *lengths )
166 [ + - ][ + - ]: 20 : mData[*i].set( *pointers, *lengths );
[ + - ]
167 : : else
168 : : {
169 [ # # ][ # # ]: 0 : MapType::iterator iter = mData.find( *i );
170 [ # # ][ # # ]: 0 : if( iter != mData.end() )
171 : : {
172 [ # # ][ # # ]: 0 : iter->second.clear();
173 [ # # ]: 0 : mData.erase( iter );
174 : : }
175 : : }
176 : : }
177 : :
178 : 2 : return MB_SUCCESS;
179 : : }
180 : :
181 : 4 : ErrorCode VarLenSparseTag::clear_data( SequenceManager* seqman, Error* /* error */, const EntityHandle* entities,
182 : : size_t num_entities, const void* value_ptr, int value_len )
183 : : {
184 [ - + ]: 4 : if( 0 == value_len )
185 : : {
186 : 0 : remove_data( seqman, 0, entities, num_entities );
187 : 0 : return MB_SUCCESS;
188 : : }
189 : :
190 [ - + ][ # # ]: 4 : ErrorCode rval = validate_lengths( NULL, &value_len, 1 );MB_CHK_ERR( rval );
191 : :
192 [ - + ][ # # ]: 4 : rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
193 : :
194 [ + + ]: 8 : for( size_t i = 0; i < num_entities; ++i )
195 : 4 : mData[entities[i]].set( value_ptr, value_len );
196 : :
197 : 4 : return MB_SUCCESS;
198 : : }
199 : :
200 : 2 : ErrorCode VarLenSparseTag::clear_data( SequenceManager* seqman, Error* /* error */, const Range& entities,
201 : : const void* value_ptr, int value_len )
202 : : {
203 [ - + ]: 2 : if( 0 == value_len )
204 : : {
205 [ # # ]: 0 : remove_data( seqman, 0, entities );
206 : 0 : return MB_SUCCESS;
207 : : }
208 : :
209 [ + - ][ - + ]: 2 : ErrorCode rval = validate_lengths( NULL, &value_len, 1 );MB_CHK_ERR( rval );
[ # # ][ # # ]
210 : :
211 [ + - ][ - + ]: 2 : rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
[ # # ][ # # ]
212 : :
213 [ + - ]: 2 : Range::const_iterator i;
214 [ + - ][ + - ]: 22 : for( i = entities.begin(); i != entities.end(); ++i )
[ + - ][ + - ]
[ + + ]
215 [ + - ][ + - ]: 20 : mData[*i].set( value_ptr, value_len );
[ + - ]
216 : :
217 : 2 : return MB_SUCCESS;
218 : : }
219 : :
220 : 760 : ErrorCode VarLenSparseTag::remove_data( SequenceManager*, Error* /* error */, const EntityHandle* entities,
221 : : size_t num_entities )
222 : : {
223 : 760 : ErrorCode result = MB_SUCCESS;
224 [ + + ]: 764 : for( size_t i = 0; i < num_entities; ++i )
225 : : {
226 [ + - ]: 760 : MapType::iterator p = mData.find( entities[i] );
227 [ + - ][ + + ]: 760 : if( p == mData.end() )
228 : 756 : return MB_TAG_NOT_FOUND;
229 : : else
230 : : {
231 [ + - ][ + - ]: 4 : p->second.clear();
232 [ + - ]: 4 : mData.erase( p );
233 : : }
234 : : }
235 : :
236 : 760 : return result;
237 : : }
238 : :
239 : 36 : ErrorCode VarLenSparseTag::remove_data( SequenceManager*, Error* /* error */, const Range& entities )
240 : : {
241 : 36 : ErrorCode result = MB_SUCCESS;
242 [ + - ][ # # ]: 36 : for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
[ + - ][ + - ]
[ + + ]
243 : : {
244 [ + - ][ + - ]: 30 : MapType::iterator p = mData.find( *i );
245 [ + - ][ + - ]: 30 : if( p == mData.end() )
246 : 30 : return MB_TAG_NOT_FOUND;
247 : : else
248 : : {
249 [ # # ][ # # ]: 0 : p->second.clear();
250 [ # # ]: 0 : mData.erase( p );
251 : : }
252 : : }
253 : :
254 : 36 : return result;
255 : : }
256 : :
257 : 1 : ErrorCode VarLenSparseTag::tag_iterate( SequenceManager*, Error* /* error */, Range::iterator&, const Range::iterator&,
258 : : void*&, bool )
259 : : {
260 [ + - ][ + - ]: 1 : MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "Cannot iterate over variable-length tag data" );
[ + - ][ - + ]
[ + - ]
261 : : }
262 : :
263 : : template < class Container >
264 : 0 : static inline void get_tagged( const VarLenSparseTag::MapType& mData, EntityType type, Container& output_range )
265 : : {
266 [ # # ][ # # ]: 0 : VarLenSparseTag::MapType::const_iterator iter;
267 [ # # ][ # # ]: 0 : typename Container::iterator hint = output_range.begin();
268 [ # # ][ # # ]: 0 : if( MBMAXTYPE == type )
269 : : {
270 [ # # ][ # # ]: 0 : for( iter = mData.begin(); iter != mData.end(); ++iter )
[ # # ][ # # ]
[ # # ][ # # ]
271 [ # # ][ # # ]: 0 : hint = output_range.insert( hint, iter->first );
[ # # ][ # # ]
272 : : }
273 : : else
274 : : {
275 : : #ifdef MOAB_HAVE_UNORDERED_MAP
276 [ # # ][ # # ]: 0 : for( iter = mData.begin(); iter != mData.end(); ++iter )
[ # # ][ # # ]
[ # # ][ # # ]
277 [ # # ][ # # ]: 0 : if( TYPE_FROM_HANDLE( iter->first ) == type ) hint = output_range.insert( hint, iter->first );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
278 : : #else
279 : : iter = mData.lower_bound( FIRST_HANDLE( type ) );
280 : : VarLenSparseTag::MapType::const_iterator end = mData.lower_bound( LAST_HANDLE( type ) + 1 );
281 : : for( ; iter != end; ++iter )
282 : : hint = output_range.insert( hint, iter->first );
283 : : #endif
284 : : }
285 : 0 : }
286 : :
287 : : template < class Container >
288 : 47 : static inline void get_tagged( const VarLenSparseTag::MapType& mData, Range::const_iterator begin,
289 : : Range::const_iterator end, Container& output_range )
290 : : {
291 [ + - ]: 47 : typename Container::iterator hint = output_range.begin();
292 [ # # ][ # # ]: 199980 : for( Range::const_iterator i = begin; i != end; ++i )
[ # # ][ + - ]
[ + - ][ + + ]
293 [ # # ][ # # ]: 199933 : if( mData.find( *i ) != mData.end() ) hint = output_range.insert( hint, *i );
[ # # ][ # # ]
[ # # ][ # # ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
294 : 47 : }
295 : :
296 : : template < class Container >
297 : 47 : static inline void get_tagged( const VarLenSparseTag::MapType& mData, Container& entities, EntityType type,
298 : : const Range* intersect )
299 : : {
300 [ # # ][ - + ]: 47 : if( !intersect )
301 : 0 : get_tagged< Container >( mData, type, entities );
302 [ # # ][ + - ]: 47 : else if( MBMAXTYPE == type )
303 : 47 : get_tagged< Container >( mData, intersect->begin(), intersect->end(), entities );
304 : : else
305 : : {
306 [ # # ][ # # ]: 0 : std::pair< Range::iterator, Range::iterator > r = intersect->equal_range( type );
307 [ # # ][ # # ]: 0 : get_tagged< Container >( mData, r.first, r.second, entities );
308 : : }
309 : 47 : }
310 : :
311 : : //! Gets all entity handles that match a type and tag
312 : 47 : ErrorCode VarLenSparseTag::get_tagged_entities( const SequenceManager*, Range& entities, EntityType type,
313 : : const Range* intersect ) const
314 : : {
315 : 47 : get_tagged( mData, entities, type, intersect );
316 : 47 : return MB_SUCCESS;
317 : : }
318 : :
319 : : //! Gets all entity handles that match a type and tag
320 : 0 : ErrorCode VarLenSparseTag::num_tagged_entities( const SequenceManager*, size_t& output_count, EntityType type,
321 : : const Range* intersect ) const
322 : : {
323 [ # # ]: 0 : InsertCount counter( output_count );
324 [ # # ]: 0 : get_tagged( mData, counter, type, intersect );
325 [ # # ]: 0 : output_count = counter.end();
326 : 0 : return MB_SUCCESS;
327 : : }
328 : :
329 : 0 : ErrorCode VarLenSparseTag::find_entities_with_value(
330 : : #ifdef MOAB_HAVE_UNORDERED_MAP
331 : : const SequenceManager* seqman,
332 : : #else
333 : : const SequenceManager*,
334 : : #endif
335 : : Error*, Range& output_entities, const void* value, int value_bytes, const EntityType type,
336 : : const Range* intersect_entities ) const
337 : : {
338 [ # # ][ # # ]: 0 : if( value_bytes && value_bytes != get_size() ) return MB_INVALID_SIZE;
[ # # ][ # # ]
339 : :
340 [ # # ][ # # ]: 0 : MapType::const_iterator iter, end;
341 : : #ifdef MOAB_HAVE_UNORDERED_MAP
342 [ # # ]: 0 : if( intersect_entities )
343 : : {
344 [ # # ]: 0 : std::pair< Range::iterator, Range::iterator > r;
345 [ # # ]: 0 : if( type == MBMAXTYPE )
346 : : {
347 [ # # ]: 0 : r.first = intersect_entities->begin();
348 [ # # ]: 0 : r.second = intersect_entities->end();
349 : : }
350 : : else
351 : : {
352 [ # # ]: 0 : r = intersect_entities->equal_range( type );
353 : : }
354 : :
355 [ # # ][ # # ]: 0 : find_map_varlen_values_equal( *this, value, get_size(), r.first, r.second, mData, output_entities );
356 : : }
357 [ # # ]: 0 : else if( type == MBMAXTYPE )
358 : : {
359 [ # # ][ # # ]: 0 : find_tag_varlen_values_equal( *this, value, get_size(), mData.begin(), mData.end(), output_entities );
360 : : }
361 : : else
362 : : {
363 [ # # ]: 0 : Range tmp;
364 [ # # ]: 0 : seqman->get_entities( type, tmp );
365 [ # # ][ # # ]: 0 : find_map_varlen_values_equal( *this, value, get_size(), tmp.begin(), tmp.end(), mData, output_entities );
[ # # ][ # # ]
366 : : }
367 : : #else
368 : : if( intersect_entities )
369 : : {
370 : : for( Range::const_pair_iterator p = intersect_entities->begin(); p != intersect_entities->end(); ++p )
371 : : {
372 : : iter = mData.lower_bound( p->first );
373 : : end = mData.upper_bound( p->second );
374 : : find_tag_varlen_values_equal( *this, value, get_size(), iter, end, output_entities );
375 : : }
376 : : }
377 : : else
378 : : {
379 : : if( type == MBMAXTYPE )
380 : : {
381 : : iter = mData.begin();
382 : : end = mData.end();
383 : : }
384 : : else
385 : : {
386 : : iter = mData.lower_bound( CREATE_HANDLE( type, MB_START_ID ) );
387 : : end = mData.upper_bound( CREATE_HANDLE( type, MB_END_ID ) );
388 : : }
389 : : find_tag_varlen_values_equal( *this, value, get_size(), iter, end, output_entities );
390 : : }
391 : : #endif
392 : :
393 : 0 : return MB_SUCCESS;
394 : : }
395 : :
396 : 96 : bool VarLenSparseTag::is_tagged( const SequenceManager*, EntityHandle h ) const
397 : : {
398 [ + - ][ + - ]: 96 : return mData.find( h ) != mData.end();
399 : : }
400 : :
401 : 0 : ErrorCode VarLenSparseTag::get_memory_use( const SequenceManager*, unsigned long& total,
402 : : unsigned long& per_entity ) const
403 : : {
404 : 0 : total = mData.size() * ( 3 * sizeof( void* ) + sizeof( VarLenTag ) );
405 [ # # ][ # # ]: 0 : for( MapType::const_iterator i = mData.begin(); i != mData.end(); ++i )
[ # # ]
406 [ # # ][ # # ]: 0 : total += i->second.mem();
407 [ # # ]: 0 : if( !mData.empty() ) per_entity = total / mData.size();
408 : 0 : total += sizeof( *this ) + TagInfo::get_memory_use();
409 : :
410 : 0 : return MB_SUCCESS;
411 : : }
412 : :
413 : : } // namespace moab
|