Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
VarLenSparseTag.cpp
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 #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 VarLenSparseTag::VarLenSparseTag( const char* name, DataType type, const void* default_value, int default_value_bytes )
31  : TagInfo( name, MB_VARIABLE_LENGTH, type, default_value, default_value_bytes )
32 {
33 }
34 
36 {
37  release_all_data( 0, 0, true );
38 }
39 
41 {
42  return MB_TAG_SPARSE;
43 }
44 
46 {
47  mData.clear();
48  return MB_SUCCESS;
49 }
50 
52  EntityHandle entity_handle,
53  const void*& ptr,
54  int& length ) const
55 {
56  MapType::const_iterator iter = mData.find( entity_handle );
57 
58  if( iter != mData.end() )
59  {
60  ptr = iter->second.data();
61  length = iter->second.size();
62  }
63  else if( get_default_value() )
64  {
65  ptr = get_default_value();
67  }
68  else
69  return MB_TAG_NOT_FOUND;
70 
71  return MB_SUCCESS;
72 }
73 
75  Error* /* error */,
76  const EntityHandle*,
77  size_t,
78  void* ) const
79 {
80  MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
81 }
82 
84  Error* /* error */,
85  const Range& /*entities*/,
86  void* /* data */ ) const
87 {
88  MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
89 }
90 
92  Error* /* error */,
93  const EntityHandle* entities,
94  size_t num_entities,
95  const void** pointers,
96  int* lengths ) const
97 {
98  if( !lengths )
99  {
100  MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
101  }
102 
103  ErrorCode rval;
104  for( size_t i = 0; i < num_entities; ++i )
105  {
106  rval = get_data_ptr( NULL, entities[i], pointers[i], lengths[i] );
107  if( rval != MB_SUCCESS ) return rval;
108  }
109 
110  return MB_SUCCESS;
111 }
112 
114  Error* /* error */,
115  const Range& entities,
116  const void** pointers,
117  int* lengths ) const
118 {
119  if( !lengths )
120  {
121  MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
122  }
123 
124  ErrorCode rval;
126  for( i = entities.begin(); i != entities.end(); ++i, ++pointers, ++lengths )
127  {
128  rval = get_data_ptr( NULL, *i, *pointers, *lengths );
129  if( rval != MB_SUCCESS ) return rval;
130  }
131 
132  return MB_SUCCESS;
133 }
134 
136  Error* /* error */,
137  const EntityHandle* /* entities */,
138  size_t /* num_entities */,
139  const void* /* data */ )
140 {
141  MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
142 }
143 
145  Error* /* error */,
146  const Range& /* entities */,
147  const void* /* data */ )
148 {
149  MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "No size specified for variable-length tag " << get_name() << " data" );
150 }
151 
153  Error* /* error */,
154  const EntityHandle* entities,
155  size_t num_entities,
156  void const* const* pointers,
157  const int* lengths )
158 {
159  ErrorCode rval = validate_lengths( NULL, lengths, num_entities );MB_CHK_ERR( rval );
160 
161  rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
162 
163  for( size_t i = 0; i < num_entities; ++i )
164  {
165  if( lengths[i] )
166  mData[entities[i]].set( pointers[i], lengths[i] );
167  else
168  {
169  MapType::iterator iter = mData.find( entities[i] );
170  if( iter != mData.end() )
171  {
172  iter->second.clear();
173  mData.erase( iter );
174  }
175  }
176  }
177 
178  return MB_SUCCESS;
179 }
180 
182  Error* /* error */,
183  const Range& entities,
184  void const* const* pointers,
185  const int* lengths )
186 {
187  ErrorCode rval = validate_lengths( NULL, lengths, entities.size() );MB_CHK_ERR( rval );
188 
189  rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
190 
192  for( i = entities.begin(); i != entities.end(); ++i, ++pointers, ++lengths )
193  {
194  if( *lengths )
195  mData[*i].set( *pointers, *lengths );
196  else
197  {
198  MapType::iterator iter = mData.find( *i );
199  if( iter != mData.end() )
200  {
201  iter->second.clear();
202  mData.erase( iter );
203  }
204  }
205  }
206 
207  return MB_SUCCESS;
208 }
209 
211  Error* /* error */,
212  const EntityHandle* entities,
213  size_t num_entities,
214  const void* value_ptr,
215  int value_len )
216 {
217  if( 0 == value_len )
218  {
219  remove_data( seqman, 0, entities, num_entities );
220  return MB_SUCCESS;
221  }
222 
223  ErrorCode rval = validate_lengths( NULL, &value_len, 1 );MB_CHK_ERR( rval );
224 
225  rval = seqman->check_valid_entities( NULL, entities, num_entities, true );MB_CHK_ERR( rval );
226 
227  for( size_t i = 0; i < num_entities; ++i )
228  mData[entities[i]].set( value_ptr, value_len );
229 
230  return MB_SUCCESS;
231 }
232 
234  Error* /* error */,
235  const Range& entities,
236  const void* value_ptr,
237  int value_len )
238 {
239  if( 0 == value_len )
240  {
241  remove_data( seqman, 0, entities );
242  return MB_SUCCESS;
243  }
244 
245  ErrorCode rval = validate_lengths( NULL, &value_len, 1 );MB_CHK_ERR( rval );
246 
247  rval = seqman->check_valid_entities( NULL, entities );MB_CHK_ERR( rval );
248 
250  for( i = entities.begin(); i != entities.end(); ++i )
251  mData[*i].set( value_ptr, value_len );
252 
253  return MB_SUCCESS;
254 }
255 
257  Error* /* error */,
258  const EntityHandle* entities,
259  size_t num_entities )
260 {
261  ErrorCode result = MB_SUCCESS;
262  for( size_t i = 0; i < num_entities; ++i )
263  {
264  MapType::iterator p = mData.find( entities[i] );
265  if( p == mData.end() )
266  return MB_TAG_NOT_FOUND;
267  else
268  {
269  p->second.clear();
270  mData.erase( p );
271  }
272  }
273 
274  return result;
275 }
276 
278 {
279  ErrorCode result = MB_SUCCESS;
280  for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
281  {
282  MapType::iterator p = mData.find( *i );
283  if( p == mData.end() )
284  return MB_TAG_NOT_FOUND;
285  else
286  {
287  p->second.clear();
288  mData.erase( p );
289  }
290  }
291 
292  return result;
293 }
294 
296  Error* /* error */,
298  const Range::iterator&,
299  void*&,
300  bool )
301 {
302  MB_SET_ERR( MB_VARIABLE_DATA_LENGTH, "Cannot iterate over variable-length tag data" );
303 }
304 
305 template < class Container >
306 static inline void get_tagged( const VarLenSparseTag::MapType& mData, EntityType type, Container& output_range )
307 {
308  VarLenSparseTag::MapType::const_iterator iter;
309  typename Container::iterator hint = output_range.begin();
310  if( MBMAXTYPE == type )
311  {
312  for( iter = mData.begin(); iter != mData.end(); ++iter )
313  hint = output_range.insert( hint, iter->first );
314  }
315  else
316  {
317 #ifdef MOAB_HAVE_UNORDERED_MAP
318  for( iter = mData.begin(); iter != mData.end(); ++iter )
319  if( TYPE_FROM_HANDLE( iter->first ) == type ) hint = output_range.insert( hint, iter->first );
320 #else
321  iter = mData.lower_bound( FIRST_HANDLE( type ) );
322  VarLenSparseTag::MapType::const_iterator end = mData.lower_bound( LAST_HANDLE( type ) + 1 );
323  for( ; iter != end; ++iter )
324  hint = output_range.insert( hint, iter->first );
325 #endif
326  }
327 }
328 
329 template < class Container >
330 static inline void get_tagged( const VarLenSparseTag::MapType& mData,
331  Range::const_iterator begin,
333  Container& output_range )
334 {
335  typename Container::iterator hint = output_range.begin();
336  for( Range::const_iterator i = begin; i != end; ++i )
337  if( mData.find( *i ) != mData.end() ) hint = output_range.insert( hint, *i );
338 }
339 
340 template < class Container >
341 static inline void get_tagged( const VarLenSparseTag::MapType& mData,
342  Container& entities,
343  EntityType type,
344  const Range* intersect )
345 {
346  if( !intersect )
347  get_tagged< Container >( mData, type, entities );
348  else if( MBMAXTYPE == type )
349  get_tagged< Container >( mData, intersect->begin(), intersect->end(), entities );
350  else
351  {
352  std::pair< Range::iterator, Range::iterator > r = intersect->equal_range( type );
353  get_tagged< Container >( mData, r.first, r.second, entities );
354  }
355 }
356 
357 //! Gets all entity handles that match a type and tag
359  Range& entities,
360  EntityType type,
361  const Range* intersect ) const
362 {
363  get_tagged( mData, entities, type, intersect );
364  return MB_SUCCESS;
365 }
366 
367 //! Gets all entity handles that match a type and tag
369  size_t& output_count,
370  EntityType type,
371  const Range* intersect ) const
372 {
373  InsertCount counter( output_count );
374  get_tagged( mData, counter, type, intersect );
375  output_count = counter.end();
376  return MB_SUCCESS;
377 }
378 
381  const SequenceManager* seqman,
382 #else
383  const SequenceManager*,
384 #endif
385  Error*,
386  Range& output_entities,
387  const void* value,
388  int value_bytes,
389  const EntityType type,
390  const Range* intersect_entities ) const
391 {
392  if( value_bytes && value_bytes != get_size() ) return MB_INVALID_SIZE;
393 
394  MapType::const_iterator iter, end;
395 #ifdef MOAB_HAVE_UNORDERED_MAP
396  if( intersect_entities )
397  {
398  std::pair< Range::iterator, Range::iterator > r;
399  if( type == MBMAXTYPE )
400  {
401  r.first = intersect_entities->begin();
402  r.second = intersect_entities->end();
403  }
404  else
405  {
406  r = intersect_entities->equal_range( type );
407  }
408 
409  find_map_varlen_values_equal( *this, value, get_size(), r.first, r.second, mData, output_entities );
410  }
411  else if( type == MBMAXTYPE )
412  {
413  find_tag_varlen_values_equal( *this, value, get_size(), mData.begin(), mData.end(), output_entities );
414  }
415  else
416  {
417  Range tmp;
418  seqman->get_entities( type, tmp );
419  find_map_varlen_values_equal( *this, value, get_size(), tmp.begin(), tmp.end(), mData, output_entities );
420  }
421 #else
422  if( intersect_entities )
423  {
424  for( Range::const_pair_iterator p = intersect_entities->begin(); p != intersect_entities->end(); ++p )
425  {
426  iter = mData.lower_bound( p->first );
427  end = mData.upper_bound( p->second );
428  find_tag_varlen_values_equal( *this, value, get_size(), iter, end, output_entities );
429  }
430  }
431  else
432  {
433  if( type == MBMAXTYPE )
434  {
435  iter = mData.begin();
436  end = mData.end();
437  }
438  else
439  {
440  iter = mData.lower_bound( CREATE_HANDLE( type, MB_START_ID ) );
441  end = mData.upper_bound( CREATE_HANDLE( type, MB_END_ID ) );
442  }
443  find_tag_varlen_values_equal( *this, value, get_size(), iter, end, output_entities );
444  }
445 #endif
446 
447  return MB_SUCCESS;
448 }
449 
451 {
452  return mData.find( h ) != mData.end();
453 }
454 
456  unsigned long& total,
457  unsigned long& per_entity ) const
458 {
459  total = mData.size() * ( 3 * sizeof( void* ) + sizeof( VarLenTag ) );
460  for( MapType::const_iterator i = mData.begin(); i != mData.end(); ++i )
461  total += i->second.mem();
462  if( !mData.empty() ) per_entity = total / mData.size();
463  total += sizeof( *this ) + TagInfo::get_memory_use();
464 
465  return MB_SUCCESS;
466 }
467 
468 } // namespace moab