Loading [MathJax]/jax/input/TeX/config.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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  35 VarLenSparseTag::~VarLenSparseTag() 36 { 37  release_all_data( 0, 0, true ); 38 } 39  40 TagType VarLenSparseTag::get_storage_type() const 41 { 42  return MB_TAG_SPARSE; 43 } 44  45 ErrorCode VarLenSparseTag::release_all_data( SequenceManager*, Error*, bool ) 46 { 47  mData.clear(); 48  return MB_SUCCESS; 49 } 50  51 ErrorCode VarLenSparseTag::get_data_ptr( Error* /* error */, 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(); 66  length = get_default_value_size(); 67  } 68  else 69  return MB_TAG_NOT_FOUND; 70  71  return MB_SUCCESS; 72 } 73  74 ErrorCode VarLenSparseTag::get_data( const SequenceManager*, 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  83 ErrorCode VarLenSparseTag::get_data( const SequenceManager*, 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  91 ErrorCode VarLenSparseTag::get_data( const SequenceManager*, 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  113 ErrorCode VarLenSparseTag::get_data( const SequenceManager*, 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; 125  Range::const_iterator i; 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  135 ErrorCode VarLenSparseTag::set_data( SequenceManager* /* seqman */, 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  144 ErrorCode VarLenSparseTag::set_data( SequenceManager* /* seqman */, 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  152 ErrorCode VarLenSparseTag::set_data( SequenceManager* seqman, 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  181 ErrorCode VarLenSparseTag::set_data( SequenceManager* seqman, 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  191  Range::const_iterator i; 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  210 ErrorCode VarLenSparseTag::clear_data( SequenceManager* seqman, 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  233 ErrorCode VarLenSparseTag::clear_data( SequenceManager* seqman, 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  249  Range::const_iterator i; 250  for( i = entities.begin(); i != entities.end(); ++i ) 251  mData[*i].set( value_ptr, value_len ); 252  253  return MB_SUCCESS; 254 } 255  256 ErrorCode VarLenSparseTag::remove_data( SequenceManager*, 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  277 ErrorCode VarLenSparseTag::remove_data( SequenceManager*, Error* /* error */, const Range& entities ) 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  295 ErrorCode VarLenSparseTag::tag_iterate( SequenceManager*, 296  Error* /* error */, 297  Range::iterator&, 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, 332  Range::const_iterator end, 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 358 ErrorCode VarLenSparseTag::get_tagged_entities( const SequenceManager*, 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 368 ErrorCode VarLenSparseTag::num_tagged_entities( const SequenceManager*, 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  379 ErrorCode VarLenSparseTag::find_entities_with_value( 380 #ifdef MOAB_HAVE_UNORDERED_MAP 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  450 bool VarLenSparseTag::is_tagged( const SequenceManager*, EntityHandle h ) const 451 { 452  return mData.find( h ) != mData.end(); 453 } 454  455 ErrorCode VarLenSparseTag::get_memory_use( const SequenceManager*, 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