1
15
16 #include <memory.h>
17 #include <algorithm>
18
19 #include "SparseTag.hpp"
20 #include "moab/Range.hpp"
21 #include "TagCompare.hpp"
22 #include "SysUtil.hpp"
23 #include "SequenceManager.hpp"
24 #include "moab/Error.hpp"
25 #include "moab/ErrorHandler.hpp"
26 #include "moab/CN.hpp"
27
28 namespace moab
29 {
30
31 SparseTag::SparseTag( const char* name, int size, DataType type, const void* default_value )
32 : TagInfo( name, size, type, default_value, size )
33 {
34 }
35
36 SparseTag::~SparseTag()
37 {
38 release_all_data( 0, 0, true );
39 }
40
41 TagType SparseTag::get_storage_type() const
42 {
43 return MB_TAG_SPARSE;
44 }
45
46 ErrorCode SparseTag::release_all_data( SequenceManager*, Error*, bool )
47 {
48 for( MapType::iterator i = mData.begin(); i != mData.end(); ++i )
49 mAllocator.destroy( i->second );
50 mData.clear();
51 return MB_SUCCESS;
52 }
53
54 ErrorCode SparseTag::set_data( Error*, EntityHandle entity_handle, const void* data )
55 {
56 #ifdef MOAB_HAVE_UNORDERED_MAP
57 MapType::iterator iter = mData.find( entity_handle );
58 #else
59 MapType::iterator iter = mData.lower_bound( entity_handle );
60 #endif
61
62
63 if( iter != mData.end() && iter->first == entity_handle ) memcpy( iter->second, data, get_size() );
64
65 else
66 {
67 void* new_data = allocate_data( entity_handle, iter, false );
68 memcpy( new_data, data, get_size() );
69 }
70
71 return MB_SUCCESS;
72 }
73
74 ErrorCode SparseTag::get_data_ptr( EntityHandle entity_handle, const void*& ptr, bool allocate ) const
75 {
76 MapType::const_iterator iter = mData.find( entity_handle );
77
78 if( iter != mData.end() )
79 ptr = iter->second;
80 else if( get_default_value() && allocate )
81 ptr = const_cast< SparseTag* >( this )->allocate_data( entity_handle, iter, allocate );
82 else
83 return MB_FAILURE;
84
85 return MB_SUCCESS;
86 }
87
88 ErrorCode SparseTag::get_data( Error* , EntityHandle entity_handle, void* data ) const
89 {
90 const void* ptr = 0;
91 ErrorCode rval = get_data_ptr( entity_handle, ptr, false );
92 if( MB_SUCCESS == rval )
93 {
94 memcpy( data, ptr, get_size() );
95 return rval;
96 }
97 else if( get_default_value() )
98 {
99 memcpy( data, get_default_value(), get_size() );
100 return MB_SUCCESS;
101 }
102 else
103 return MB_TAG_NOT_FOUND;
104 }
105
106 ErrorCode SparseTag::remove_data( Error* , EntityHandle entity_handle )
107 {
108 MapType::iterator i = mData.find( entity_handle );
109 if( i == mData.end() ) return MB_TAG_NOT_FOUND;
110
111 mAllocator.destroy( i->second );
112 mData.erase( i );
113
114 return MB_SUCCESS;
115 }
116
117 ErrorCode SparseTag::get_data( const SequenceManager*,
118 Error* ,
119 const EntityHandle* entities,
120 size_t num_entities,
121 void* data ) const
122 {
123 ErrorCode rval;
124 unsigned char* ptr = reinterpret_cast< unsigned char* >( data );
125 for( size_t i = 0; i < num_entities; ++i, ptr += get_size() )
126 {
127 rval = get_data( NULL, entities[i], ptr );
128 if( MB_SUCCESS != rval ) return rval;
129 }
130
131 return MB_SUCCESS;
132 }
133
134 ErrorCode SparseTag::get_data( const SequenceManager*, Error* , const Range& entities, void* data ) const
135 {
136 ErrorCode rval;
137 unsigned char* ptr = reinterpret_cast< unsigned char* >( data );
138 Range::const_iterator i;
139 for( i = entities.begin(); i != entities.end(); ++i, ptr += get_size() )
140 {
141 rval = get_data( NULL, *i, ptr );
142 if( MB_SUCCESS != rval ) return rval;
143 }
144
145 return MB_SUCCESS;
146 }
147
148 ErrorCode SparseTag::get_data( const SequenceManager*,
149 Error* ,
150 const EntityHandle* entities,
151 size_t num_entities,
152 const void** pointers,
153 int* data_lengths ) const
154 {
155 if( data_lengths )
156 {
157 int len = get_size();
158 SysUtil::setmem( data_lengths, &len, sizeof( int ), num_entities );
159 }
160
161 ErrorCode rval = MB_SUCCESS, rval_tmp;
162 for( size_t i = 0; i < num_entities; ++i, ++pointers )
163 {
164 rval_tmp = get_data_ptr( entities[i], *pointers );
165 if( MB_SUCCESS != rval_tmp && get_default_value() )
166 {
167 *pointers = get_default_value();
168 }
169 else if( MB_SUCCESS != rval_tmp )
170 {
171 return MB_TAG_NOT_FOUND;
172 }
173 }
174
175 return rval;
176 }
177
178 ErrorCode SparseTag::get_data( const SequenceManager*,
179 Error* ,
180 const Range& entities,
181 const void** pointers,
182 int* data_lengths ) const
183 {
184 if( data_lengths )
185 {
186 int len = get_size();
187 SysUtil::setmem( data_lengths, &len, sizeof( int ), entities.size() );
188 }
189
190 ErrorCode rval = MB_SUCCESS, rval_tmp;
191 Range::const_iterator i;
192 for( i = entities.begin(); i != entities.end(); ++i, ++pointers )
193 {
194 rval_tmp = get_data_ptr( *i, *pointers );
195 if( MB_SUCCESS != rval_tmp && get_default_value() )
196 {
197 *pointers = get_default_value();
198 }
199 else if( MB_SUCCESS != rval_tmp )
200 {
201 return MB_TAG_NOT_FOUND;
202 }
203 }
204
205 return rval;
206 }
207
208 ErrorCode SparseTag::set_data( SequenceManager* seqman,
209 Error* ,
210 const EntityHandle* entities,
211 size_t num_entities,
212 const void* data )
213 {
214 ErrorCode rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
215
216 const unsigned char* ptr = reinterpret_cast< const unsigned char* >( data );
217 for( size_t i = 0; i < num_entities; ++i, ptr += get_size() )
218 {
219 rval = set_data( NULL, entities[i], ptr );MB_CHK_ERR( rval );
220 }
221
222 return MB_SUCCESS;
223 }
224
225 ErrorCode SparseTag::set_data( SequenceManager* seqman, Error* , const Range& entities, const void* data )
226 {
227 ErrorCode rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
228
229 const unsigned char* ptr = reinterpret_cast< const unsigned char* >( data );
230 Range::const_iterator i;
231 for( i = entities.begin(); i != entities.end(); ++i, ptr += get_size() )
232 if( MB_SUCCESS != ( rval = set_data( NULL, *i, ptr ) ) ) return rval;
233
234 return MB_SUCCESS;
235 }
236
237 ErrorCode SparseTag::set_data( SequenceManager* seqman,
238 Error* ,
239 const EntityHandle* entities,
240 size_t num_entities,
241 void const* const* pointers,
242 const int* lengths )
243 {
244 ErrorCode rval = validate_lengths( NULL, lengths, num_entities );MB_CHK_ERR( rval );
245
246 rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
247
248 for( size_t i = 0; i < num_entities; ++i, ++pointers )
249 {
250 rval = set_data( NULL, entities[i], *pointers );MB_CHK_ERR( rval );
251 }
252
253 return MB_SUCCESS;
254 }
255
256 ErrorCode SparseTag::set_data( SequenceManager* seqman,
257 Error* ,
258 const Range& entities,
259 void const* const* pointers,
260 const int* lengths )
261 {
262 ErrorCode rval = validate_lengths( NULL, lengths, entities.size() );MB_CHK_ERR( rval );
263
264 rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
265
266 Range::const_iterator i;
267 for( i = entities.begin(); i != entities.end(); ++i, ++pointers )
268 {
269 rval = set_data( NULL, *i, *pointers );MB_CHK_ERR( rval );
270 }
271
272 return MB_SUCCESS;
273 }
274
275 ErrorCode SparseTag::clear_data( SequenceManager* seqman,
276 Error* ,
277 const EntityHandle* entities,
278 size_t num_entities,
279 const void* value_ptr,
280 int value_len )
281 {
282 if( value_len && value_len != get_size() )
283 {
284 MB_SET_ERR( MB_INVALID_SIZE, "Invalid data size " << get_size() << " specified for sparse tag " << get_name()
285 << " of size " << value_len );
286 }
287
288 ErrorCode rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
289
290 for( size_t i = 0; i < num_entities; ++i )
291 {
292 rval = set_data( NULL, entities[i], value_ptr );MB_CHK_ERR( rval );
293 }
294
295 return MB_SUCCESS;
296 }
297
298 ErrorCode SparseTag::clear_data( SequenceManager* seqman,
299 Error* ,
300 const Range& entities,
301 const void* value_ptr,
302 int value_len )
303 {
304 if( value_len && value_len != get_size() )
305 {
306 MB_SET_ERR( MB_INVALID_SIZE, "Invalid data size " << get_size() << " specified for sparse tag " << get_name()
307 << " of size " << value_len );
308 }
309
310 ErrorCode rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
311
312 Range::const_iterator i;
313 for( i = entities.begin(); i != entities.end(); ++i )
314 {
315 rval = set_data( NULL, *i, value_ptr );MB_CHK_ERR( rval );
316 }
317
318 return MB_SUCCESS;
319 }
320
321 ErrorCode SparseTag::remove_data( SequenceManager*,
322 Error* ,
323 const EntityHandle* entities,
324 size_t num_entities )
325 {
326 ErrorCode rval;
327 for( size_t i = 0; i < num_entities; ++i )
328 {
329 rval = remove_data( NULL, entities[i] );
330 if( MB_SUCCESS != rval ) return rval;
331 }
332
333 return MB_SUCCESS;
334 }
335
336 ErrorCode SparseTag::remove_data( SequenceManager*, Error* , const Range& entities )
337 {
338 for( Range::const_iterator i = entities.begin(); i != entities.end(); ++i )
339 if( MB_SUCCESS != remove_data( NULL, *i ) ) return MB_TAG_NOT_FOUND;
340
341 return MB_SUCCESS;
342 }
343
344 ErrorCode SparseTag::tag_iterate( SequenceManager* seqman,
345 Error* ,
346 Range::iterator& iter,
347 const Range::iterator& end,
348 void*& data_ptr,
349 bool allocate )
350 {
351
352
353
354
355
356
357
358 if( iter == end ) return MB_SUCCESS;
359
360
361
362
363 ErrorCode rval = seqman->check_valid_entities( NULL, &*iter, 1 );MB_CHK_ERR( rval );
364
365
366 const void* ptr = NULL;
367 rval = get_data_ptr( *iter, ptr );
368 if( MB_SUCCESS == rval )
369 data_ptr = const_cast< void* >( ptr );
370 else if( get_default_value() && allocate )
371 {
372 ptr = allocate_data( *iter, mData.end() );
373 data_ptr = const_cast< void* >( ptr );
374 }
375 else
376 {
377
378
379 if( get_default_value() && !allocate ) ++iter;
380
381 }
382
383
384 ++iter;
385 return MB_SUCCESS;
386 }
387
388 template < class Container >
389 static inline void get_tagged( const SparseTag::MapType& mData, EntityType type, Container& output_range )
390 {
391 SparseTag::MapType::const_iterator iter;
392 typename Container::iterator hint = output_range.begin();
393 if( MBMAXTYPE == type )
394 {
395 for( iter = mData.begin(); iter != mData.end(); ++iter )
396 hint = output_range.insert( hint, iter->first );
397 }
398 else
399 {
400 #ifdef MOAB_HAVE_UNORDERED_MAP
401 for( iter = mData.begin(); iter != mData.end(); ++iter )
402 if( TYPE_FROM_HANDLE( iter->first ) == type ) hint = output_range.insert( hint, iter->first );
403 #else
404 iter = mData.lower_bound( FIRST_HANDLE( type ) );
405 SparseTag::MapType::const_iterator end = mData.lower_bound( LAST_HANDLE( type ) + 1 );
406 for( ; iter != end; ++iter )
407 hint = output_range.insert( hint, iter->first );
408 #endif
409 }
410 }
411
412 template < class Container >
413 static inline void get_tagged( const SparseTag::MapType& mData,
414 Range::const_iterator begin,
415 Range::const_iterator end,
416 Container& output_range )
417 {
418 typename Container::iterator hint = output_range.begin();
419 for( Range::const_iterator i = begin; i != end; ++i )
420 if( mData.find( *i ) != mData.end() ) hint = output_range.insert( hint, *i );
421 }
422
423 template < class Container >
424 static inline void get_tagged( const SparseTag::MapType& mData,
425 Container& entities,
426 EntityType type,
427 const Range* intersect )
428 {
429 if( !intersect )
430 get_tagged< Container >( mData, type, entities );
431 else if( MBMAXTYPE == type )
432 get_tagged< Container >( mData, intersect->begin(), intersect->end(), entities );
433 else
434 {
435 std::pair< Range::iterator, Range::iterator > r = intersect->equal_range( type );
436 get_tagged< Container >( mData, r.first, r.second, entities );
437 }
438 }
439
440
441 ErrorCode SparseTag::get_tagged_entities( const SequenceManager*,
442 Range& output_range,
443 EntityType type,
444 const Range* intersect ) const
445 {
446 get_tagged( mData, output_range, type, intersect );
447 return MB_SUCCESS;
448 }
449
450
451 ErrorCode SparseTag::num_tagged_entities( const SequenceManager*,
452 size_t& output_count,
453 EntityType type,
454 const Range* intersect ) const
455 {
456 InsertCount counter( output_count );
457 get_tagged( mData, counter, type, intersect );
458 output_count = counter.end();
459 return MB_SUCCESS;
460 }
461
462 ErrorCode SparseTag::find_entities_with_value(
463 #ifdef MOAB_HAVE_UNORDERED_MAP
464 const SequenceManager* seqman,
465 #else
466 const SequenceManager*,
467 #endif
468 Error* ,
469 Range& output_entities,
470 const void* value,
471 int value_bytes,
472 EntityType type,
473 const Range* intersect_entities ) const
474 {
475 if( value_bytes && value_bytes != get_size() )
476 {
477 MB_SET_ERR( MB_INVALID_SIZE, "Invalid data size " << get_size() << " specified for sparse tag " << get_name()
478 << " of size " << value_bytes );
479 }
480
481 MapType::const_iterator iter, end;
482 #ifdef MOAB_HAVE_UNORDERED_MAP
483 if( intersect_entities )
484 {
485 std::pair< Range::iterator, Range::iterator > r;
486 if( type == MBMAXTYPE )
487 {
488 r.first = intersect_entities->begin();
489 r.second = intersect_entities->end();
490 }
491 else
492 {
493 r = intersect_entities->equal_range( type );
494 }
495
496 find_map_values_equal( *this, value, get_size(), r.first, r.second, mData, output_entities );
497 }
498 else if( type == MBMAXTYPE )
499 {
500 find_tag_values_equal( *this, value, get_size(), mData.begin(), mData.end(), output_entities );
501 }
502 else
503 {
504 Range tmp;
505 seqman->get_entities( type, tmp );
506 find_map_values_equal( *this, value, get_size(), tmp.begin(), tmp.end(), mData, output_entities );
507 }
508 #else
509 if( intersect_entities )
510 {
511 for( Range::const_pair_iterator p = intersect_entities->begin(); p != intersect_entities->end(); ++p )
512 {
513 iter = mData.lower_bound( p->first );
514 end = mData.upper_bound( p->second );
515 find_tag_values_equal( *this, value, get_size(), iter, end, output_entities );
516 }
517 }
518 else
519 {
520 if( type == MBMAXTYPE )
521 {
522 iter = mData.begin();
523 end = mData.end();
524 }
525 else
526 {
527 iter = mData.lower_bound( CREATE_HANDLE( type, MB_START_ID ) );
528 end = mData.upper_bound( CREATE_HANDLE( type, MB_END_ID ) );
529 }
530 find_tag_values_equal( *this, value, get_size(), iter, end, output_entities );
531 }
532 #endif
533
534 return MB_SUCCESS;
535 }
536
537 bool SparseTag::is_tagged( const SequenceManager*, EntityHandle h ) const
538 {
539 return mData.find( h ) != mData.end();
540 }
541
542 ErrorCode SparseTag::get_memory_use( const SequenceManager*, unsigned long& total, unsigned long& per_entity ) const
543
544 {
545 per_entity = get_size() + 4 * sizeof( void* );
546 total = ( mData.size() * per_entity ) + sizeof( *this ) + TagInfo::get_memory_use();
547
548 return MB_SUCCESS;
549 }
550
551 }