[MOAB-dev] r1271 - MOAB/trunk

tautges at mcs.anl.gov tautges at mcs.anl.gov
Thu Sep 13 09:29:07 CDT 2007


Author: tautges
Date: 2007-09-13 09:29:07 -0500 (Thu, 13 Sep 2007)
New Revision: 1271

Added:
   MOAB/trunk/ReadParallel.cpp
   MOAB/trunk/ReadParallel.hpp
Modified:
   MOAB/trunk/MBCore.cpp
   MOAB/trunk/Makefile.am
   MOAB/trunk/TagServer.cpp
   MOAB/trunk/TagServer.hpp
Log:
Adding ReadParallel class to handle reading in parallel
(implementation of read and delete partially done).

NOTE: changed the options for PARALLEL= to NONE, BCAST, BCAST_DELETE,
SCATTER, to correspond to what we did for geometry.

Fixed get_entities_with_type_and_tag implementations in case where set
is input, either empty or not.  Also condensed implementation a fair
amount.

Implemented switch cases for MB_TAG_LAST in TagServer to eliminate
compiler warnings.

Passes all tests in make check, except for iMesh testc_cbind (will
check that next, may have something to do with configuration)



Modified: MOAB/trunk/MBCore.cpp
===================================================================
--- MOAB/trunk/MBCore.cpp	2007-09-12 22:59:16 UTC (rev 1270)
+++ MOAB/trunk/MBCore.cpp	2007-09-13 14:29:07 UTC (rev 1271)
@@ -39,6 +39,8 @@
 #include "MBReaderWriterSet.hpp"
 #include "MBReaderIface.hpp"
 #include "MBWriterIface.hpp"
+#include "ReadParallel.hpp"
+
 #ifdef HDF5_FILE
 #  include "WriteHDF5.hpp"
    typedef WriteHDF5 DefaultWriter;
@@ -353,108 +355,41 @@
     num_blocks = num_set_tag_values;
   }
   
-    // Get parallel settings
-  int parallel_mode;
-  const char* parallel_opts[] = { "NONE", "SEND", "FORMAT", 0 };
-  rval = opts.match_option( "PARALLEL", parallel_opts, parallel_mode );
-  if (MB_FAILURE == rval) {
-    mError->set_last_error( "Unexpected value for 'PARALLEL' option\n" );
-    return MB_FAILURE;
+    // if reading in parallel, call a different reader
+  std::string parallel_opt;
+  rval = opts.get_option( "PARALLEL", parallel_opt);
+  if (MB_SUCCESS == rval && !parallel_opt.empty()) {
+    return ReadParallel(this).load_file(file_name, file_set, opts,
+                                        block_id_list, num_blocks);
   }
-  else if (MB_ENTITY_NOT_FOUND == rval) {
-    parallel_mode = 0;
+
+    // otherwise try using the file extension to select a reader
+  MBReaderIface* reader = set->get_file_extension_reader( file_name );
+  if (reader)
+  { 
+    rval = reader->load_file( file_name, file_set, opts, block_id_list, num_blocks );
+    delete reader;
   }
-    // Get partition setting
-  bool do_partition = false;
-  rval = opts.get_null_option( "PARTITION" );
-  if (MB_SUCCESS == rval) 
-    do_partition = true;
-  else if (MB_ENTITY_NOT_FOUND != rval) {
-    mError->set_last_error( "Unexpected value for 'PARTITION' option\n" );
-    return MB_FAILURE;
-  }
-    // get MPI IO processor rank
-  int reader_rank;
-  rval = opts.get_int_option( "MPI_IO_RANK", reader_rank );
-  if (MB_ENTITY_NOT_FOUND == rval)
-    reader_rank = 0;
-  else if (MB_SUCCESS != rval) {
-    mError->set_last_error( "Unexpected value for 'MPI_IO_RANK' option\n" );
-    return MB_FAILURE;
-  }
-  
-  
-    // now that we've parsed all the parallel options, return
-    // failure for most of them because we haven't implemented 
-    // most of them yet.
-  if (parallel_mode == 2) {
-    mError->set_last_error( "Access to format-specific parallel read not implemented.\n");
-    return MB_NOT_IMPLEMENTED;
-  }
-  if (do_partition && parallel_mode == 1) {
-    mError->set_last_error( "Partitioning for PARALLEL=SEND not supported yet.\n");
-    return MB_NOT_IMPLEMENTED;
-  }
-  
-  if (parallel_mode != 1 || reader_rank == (int)proc_config().rank()) {
-      // Try using the file extension to select a reader
-    MBReaderIface* reader = set->get_file_extension_reader( file_name );
-    if (reader)
-    { 
-      rval = reader->load_file( file_name, file_set, opts, block_id_list, num_blocks );
-      delete reader;
-    }
-    else
-    {  
-        // Try all the readers
-      MBReaderWriterSet::iterator iter;
-      for (iter = set->begin(); iter != set->end(); ++iter)
+  else
+  {  
+      // Try all the readers
+    MBReaderWriterSet::iterator iter;
+    for (iter = set->begin(); iter != set->end(); ++iter)
+    {
+      MBReaderIface* reader = iter->make_reader( this );
+      if (NULL != reader)
       {
-        MBReaderIface* reader = iter->make_reader( this );
-        if (NULL != reader)
-        {
-          rval = reader->load_file( file_name, file_set, opts, block_id_list, num_blocks );
-          delete reader;
-          if (MB_SUCCESS == rval)
-            break;
-        }
+        rval = reader->load_file( file_name, file_set, opts, block_id_list, num_blocks );
+        delete reader;
+        if (MB_SUCCESS == rval)
+          break;
       }
     }
   }
-  else {
-    rval = MB_SUCCESS;
-  }
   
-  if (parallel_mode == 1) {
-    MBRange entities; 
-    if (MB_SUCCESS == rval && reader_rank == (int)proc_config().rank()) {
-      rval = get_entities_by_handle( file_set, entities );
-      if (MB_SUCCESS != rval)
-        entities.clear();
-    }
-    
-    MBParallelComm tool( this, tagServer, sequenceManager );
-    MBErrorCode tmp_rval = tool.broadcast_entities( reader_rank, entities );
-    if (MB_SUCCESS != rval)
-      tmp_rval = rval;
-      
-    if (MB_SUCCESS == rval && reader_rank != (int)proc_config().rank()) {
-      rval = create_meshset( MESHSET_SET, file_set );
-      if (MB_SUCCESS == rval) {
-        rval = add_entities( file_set, entities );
-        if (MB_SUCCESS != rval) {
-          delete_entities( &file_set, 1 );
-          file_set = 0;
-        }
-      }
-    }
-  } 
-  
   return rval; 
 }
-  
 
-
 MBErrorCode  MBCore::write_mesh(const char *file_name,
                                   const MBEntityHandle *output_list,
                                   const int num_sets)
@@ -1244,27 +1179,33 @@
 {
   if (recursive && type == MBENTITYSET)  // will never return anything
     return MB_TYPE_OUT_OF_RANGE;
-  
+
   MBErrorCode result;
-  if (meshset) {
-    MBRange tmp_range;
-    result = get_entities_by_type( meshset, type, tmp_range, recursive );
-    if (MB_SUCCESS != result)
-      return result;
-    result = tagServer->get_entities_with_tag_values(tmp_range, type, 
-                                                     tags, values, num_tags, 
-                                                     entities, condition); 
-    entities.merge( tmp_range ); 
+  MBRange tmp_range;
+
+  result = get_entities_by_type( meshset, type, tmp_range, recursive );
+  if (MB_SUCCESS != result)
+    return result;
+
+    // if range is empty, return right away; if intersecting condition, 
+    // empty the list too
+  if (tmp_range.empty()) {
+    if (MBInterface::INTERSECT == condition) entities.clear();
+    return MB_SUCCESS;
   }
+  else if (!entities.empty() && MBInterface::INTERSECT == condition) {
+    entities = entities.intersect(tmp_range);
+    if (entities.empty()) return MB_SUCCESS;
+    tmp_range = entities;
+  }
+    
+  result = tagServer->get_entities_with_tag_values(tmp_range, type, 
+                                                   tags, values, num_tags, 
+                                                   entities, condition); 
   
-  else 
-    result = tagServer->get_entities_with_tag_values( type, tags, values, num_tags, 
-                                                      entities, condition);
-  
   return result;
 }
 
-
 MBErrorCode MBCore::get_entities_by_handle(const MBEntityHandle meshset,
                                              MBRange &entities,
                                              const bool recursive) const

Modified: MOAB/trunk/Makefile.am
===================================================================
--- MOAB/trunk/Makefile.am	2007-09-12 22:59:16 UTC (rev 1270)
+++ MOAB/trunk/Makefile.am	2007-09-13 14:29:07 UTC (rev 1271)
@@ -145,6 +145,8 @@
   PolyEntitySequence.hpp \
   ReadGmsh.cpp \
   ReadGmsh.hpp \
+  ReadParallel.hpp \
+  ReadParallel.cpp \
   ReadSTL.cpp \
   ReadSTL.hpp \
   ReadVtk.cpp \

Added: MOAB/trunk/ReadParallel.cpp
===================================================================
--- MOAB/trunk/ReadParallel.cpp	                        (rev 0)
+++ MOAB/trunk/ReadParallel.cpp	2007-09-13 14:29:07 UTC (rev 1271)
@@ -0,0 +1,230 @@
+#include "ReadParallel.hpp"
+#include "MBCore.hpp"
+#include "MBProcConfig.hpp"
+#include "FileOptions.hpp"
+#include "MBError.hpp"
+#include "MBReaderWriterSet.hpp"
+#include "MBParallelComm.hpp"
+
+#define RR if (MB_SUCCESS != result) return result
+
+MBErrorCode ReadParallel::load_file(const char *file_name,
+                                    MBEntityHandle& file_set,
+                                    const FileOptions &opts,
+                                    const int* material_set_list,
+                                    const int num_material_sets ) 
+{
+  MBError *merror = ((MBCore*)mbImpl)->get_error_handler();
+
+  MBCore *impl = dynamic_cast<MBCore*>(mbImpl);
+  
+    // Get parallel settings
+  int parallel_mode;
+  const char* parallel_opts[] = { "NONE", "BCAST", "BCAST_DELETE", "SCATTER", 
+                                  "FORMAT", 0 };
+  enum ParallelOpts {POPT_NONE=0, POPT_BCAST, POPT_BCAST_DELETE, POPT_SCATTER,
+                     POPT_FORMAT, POPT_LAST};
+      
+  MBErrorCode rval = opts.match_option( "PARALLEL", parallel_opts, 
+                                        parallel_mode );
+  if (MB_FAILURE == rval) {
+    merror->set_last_error( "Unexpected value for 'PARALLEL' option\n" );
+    return MB_FAILURE;
+  }
+  else if (MB_ENTITY_NOT_FOUND == rval) {
+    parallel_mode = 0;
+  }
+    // Get partition setting
+  std::string partition_tag;
+  rval = opts.get_option("PARTITION", partition_tag);
+  if (MB_ENTITY_NOT_FOUND == rval || partition_tag.empty())
+    partition_tag += "PARTITION";
+
+    // get MPI IO processor rank
+  int reader_rank;
+  rval = opts.get_int_option( "MPI_IO_RANK", reader_rank );
+  if (MB_ENTITY_NOT_FOUND == rval)
+    reader_rank = 0;
+  else if (MB_SUCCESS != rval) {
+    merror->set_last_error( "Unexpected value for 'MPI_IO_RANK' option\n" );
+    return MB_FAILURE;
+  }
+  
+    // now that we've parsed all the parallel options, return
+    // failure for most of them because we haven't implemented 
+    // most of them yet.
+  if (parallel_mode == POPT_FORMAT) {
+    merror->set_last_error( "Access to format-specific parallel read not implemented.\n");
+    return MB_NOT_IMPLEMENTED;
+  }
+
+  if (parallel_mode == POPT_SCATTER) {
+    merror->set_last_error( "Partitioning for PARALLEL=SCATTER not supported yet.\n");
+    return MB_NOT_IMPLEMENTED;
+  }
+  
+  if (parallel_mode != POPT_SCATTER || 
+      reader_rank == (int)(mbImpl->proc_config().rank())) {
+      // Try using the file extension to select a reader
+    const MBReaderWriterSet* set = impl->reader_writer_set();
+    MBReaderIface* reader = set->get_file_extension_reader( file_name );
+    if (reader)
+    { 
+      rval = reader->load_file( file_name, file_set, opts, 
+                                material_set_list, num_material_sets );
+      delete reader;
+    }
+    else
+    {  
+        // Try all the readers
+      MBReaderWriterSet::iterator iter;
+      for (iter = set->begin(); iter != set->end(); ++iter)
+      {
+        MBReaderIface* reader = iter->make_reader( mbImpl );
+        if (NULL != reader)
+        {
+          rval = reader->load_file( file_name, file_set, opts, 
+                                    material_set_list, num_material_sets );
+          delete reader;
+          if (MB_SUCCESS == rval)
+            break;
+        }
+      }
+    }
+  }
+  else {
+    rval = MB_SUCCESS;
+  }
+  
+  if (parallel_mode == POPT_BCAST ||
+      parallel_mode == POPT_BCAST_DELETE) {
+    MBRange entities; 
+    if (MB_SUCCESS == rval && 
+        reader_rank == (int)(mbImpl->proc_config().rank())) {
+      rval = mbImpl->get_entities_by_handle( file_set, entities );
+      if (MB_SUCCESS != rval)
+        entities.clear();
+    }
+    
+    MBParallelComm tool( mbImpl, impl->tag_server(), impl->sequence_manager());
+    MBErrorCode tmp_rval = tool.broadcast_entities( reader_rank, entities );
+    if (MB_SUCCESS != rval && mbImpl->proc_config().size() != 1)
+      tmp_rval = rval;
+    else if (MB_SUCCESS != rval) rval = MB_SUCCESS;
+      
+    if (MB_SUCCESS == rval && 
+        reader_rank != (int)(mbImpl->proc_config().rank())) {
+      rval = mbImpl->create_meshset( MESHSET_SET, file_set );
+      if (MB_SUCCESS == rval) {
+        rval = mbImpl->add_entities( file_set, entities );
+        if (MB_SUCCESS != rval) {
+          mbImpl->delete_entities( &file_set, 1 );
+          file_set = 0;
+        }
+      }
+    }
+
+    if (parallel_mode == POPT_BCAST_DELETE)
+      rval = delete_nonlocal_entities(partition_tag, file_set);
+    
+  }
+  
+  return rval;
+}
+
+MBErrorCode ReadParallel::delete_nonlocal_entities(std::string &partition_name,
+                                                   MBEntityHandle file_set) 
+{
+  MBErrorCode result;
+  MBError *merror = ((MBCore*)mbImpl)->get_error_handler();
+  
+    // get entities in this partition
+  int my_rank = (int)mbImpl->proc_config().rank();
+  if (my_rank == 0 && mbImpl->proc_config().size() == 1) my_rank = 1;
+  int *my_rank_ptr = &my_rank;
+  MBTag partition_tag;
+  
+  result = mbImpl->tag_get_handle(partition_name.c_str(), partition_tag);
+  if (MB_TAG_NOT_FOUND == result) {
+    merror->set_last_error( "Couldn't find partition tag\n");
+    return result;
+  }
+  else if (MB_SUCCESS != result) return result;
+    
+  MBRange partition_sets;
+  result = mbImpl->get_entities_by_type_and_tag(file_set, MBENTITYSET,
+                                                &partition_tag, 
+                                                (const void* const *) &my_rank_ptr, 
+                                                1, partition_sets); RR;
+  if (MB_SUCCESS != result || partition_sets.empty()) return result;
+  
+  MBRange file_ents, partition_ents, exist_ents, all_ents;
+
+    // get ents in the partition
+  for (MBRange::iterator rit = partition_sets.begin(); 
+       rit != partition_sets.end(); rit++) {
+    result = mbImpl->get_entities_by_handle(*rit, partition_ents, 
+                                            MBInterface::UNION); RR;
+  }
+
+    // get pre-existing ents, which are all entities minus file ents
+  result = mbImpl->get_entities_by_handle(0, all_ents); RR;
+  result = mbImpl->get_entities_by_handle(file_set, file_ents); RR;
+  exist_ents = all_ents.subtract(file_ents);
+
+    // merge partition ents into pre-existing entities
+  exist_ents.merge(partition_ents);
+  
+    // gather adjacent verts and add to existing ents
+  MBRange tmp_ents;
+  MBRange::iterator bit = exist_ents.lower_bound(MBEDGE),
+    eit = exist_ents.upper_bound(MBENTITYSET);
+  MBRange from_ents(*bit, *eit);
+  from_ents = from_ents.intersect(exist_ents);
+  result = mbImpl->get_adjacencies(from_ents, 0, false, tmp_ents, 
+                                   MBInterface::UNION); RR;
+  exist_ents.merge(tmp_ents);
+  
+    // subtract from all ents to get deletable ents
+  all_ents = all_ents.subtract(exist_ents);
+  
+    // now go through the sets to see if we should keep any
+  MBRange all_sets, deletable_sets;
+  result = mbImpl->get_entities_by_type(0, MBENTITYSET, all_sets);
+  for (MBRange::iterator rit = all_sets.begin(); rit != all_sets.end(); rit++) {
+    tmp_ents.clear();
+    result = mbImpl->get_entities_by_handle(*rit, tmp_ents); RR;
+    tmp_ents = tmp_ents.intersect(exist_ents);
+    
+      // if the intersection is empty, set is deletable
+    if (tmp_ents.empty()) deletable_sets.insert(*rit);
+  }
+  
+    // now delete sets first, then ents
+  result = mbImpl->delete_entities(deletable_sets); RR;
+  result = mbImpl->delete_entities(all_ents); RR;
+  
+    // finally, look for sparse tags which have no entities, and delete
+    // those too
+  std::vector<MBTag> all_tags;
+  result = mbImpl->tag_get_tags(all_tags);
+  MBTag *tag_vec = &all_tags[0];
+  for (unsigned int i = 0; i < all_tags.size(); i++) {
+      // get type first, and continue if not sparse
+    MBTagType this_type;
+    result = mbImpl->tag_get_type(tag_vec[i], this_type); RR;
+    if (MB_TAG_SPARSE != this_type) continue;
+    
+      // get ents with this tag; should be efficient for sparse tags
+    tmp_ents.clear();
+    result = mbImpl->get_entities_by_type_and_tag(0, MBMAXTYPE, 
+                                                  tag_vec+i, NULL,
+                                                  1, tmp_ents); RR;
+    if (tmp_ents.empty()) {
+        // no entities with this tag - delete the tag
+      result = mbImpl->tag_delete(tag_vec[i]); RR;
+    }
+  }
+  
+  return MB_SUCCESS;
+}

Added: MOAB/trunk/ReadParallel.hpp
===================================================================
--- MOAB/trunk/ReadParallel.hpp	                        (rev 0)
+++ MOAB/trunk/ReadParallel.hpp	2007-09-13 14:29:07 UTC (rev 1271)
@@ -0,0 +1,38 @@
+#ifndef READ_PARALLEL_HPP
+#define READ_PARALLEL_HPP
+
+#include "MBForward.hpp"
+#include "MBReaderIface.hpp"
+
+class MBReadUtilIface;
+
+class ReadParallel : public MBReaderIface
+{
+   
+public:
+
+  static MBReaderIface* factory( MBInterface* );
+
+    //! load a file
+  MBErrorCode load_file(const char *file_name,
+                        MBEntityHandle& file_set,
+                        const FileOptions &opts,
+                        const int* material_set_list,
+                        const int num_material_sets );
+  
+    //! Constructor
+  ReadParallel(MBInterface* impl = NULL) {mbImpl = impl;};
+
+   //! Destructor
+  virtual ~ReadParallel() {}
+
+protected:
+
+private:
+  MBInterface *mbImpl;
+  
+  MBErrorCode delete_nonlocal_entities(std::string &partition_name,
+                                       MBEntityHandle file_set);
+};
+
+#endif

Modified: MOAB/trunk/TagServer.cpp
===================================================================
--- MOAB/trunk/TagServer.cpp	2007-09-12 22:59:16 UTC (rev 1270)
+++ MOAB/trunk/TagServer.cpp	2007-09-13 14:29:07 UTC (rev 1271)
@@ -155,6 +155,9 @@
     case MB_TAG_MESH:
       result = MB_SUCCESS;
       break;
+    case MB_TAG_LAST:
+      assert(false);
+      break;
   }
   
   if (MB_SUCCESS != result)
@@ -186,6 +189,9 @@
     case MB_TAG_MESH:
       status = MB_SUCCESS;
       break;
+    case MB_TAG_LAST:
+      assert(false);
+      break;
   }
   
   mTagTable[tag_type][tag_idx].invalidate();
@@ -266,6 +272,8 @@
       return mDenseData->set_data(id, entity_handle, data);
     case MB_TAG_MESH:
       return MB_FAILURE;
+    case MB_TAG_LAST:
+      return MB_FAILURE;
   }
   return MB_FAILURE;
 }
@@ -422,6 +430,10 @@
     case MB_TAG_MESH:
       result = MB_FAILURE;
       break;
+    case MB_TAG_LAST:
+      assert(false);
+      result = MB_FAILURE;
+      break;
   }
 
   // if we couldn't get a value
@@ -679,6 +691,8 @@
       return MB_FAILURE;
     case MB_TAG_MESH:
       return MB_FAILURE;
+    case MB_TAG_LAST:
+      return MB_FAILURE;
   }
   
   return MB_TAG_NOT_FOUND;
@@ -721,6 +735,9 @@
     case MB_TAG_MESH:
       result = MB_TYPE_OUT_OF_RANGE;
       break;
+    case MB_TAG_LAST:
+      result = MB_TYPE_OUT_OF_RANGE;
+      break;
   }
   
   return result;
@@ -746,6 +763,9 @@
     case MB_TAG_MESH:
       result = MB_TYPE_OUT_OF_RANGE;
       break;
+    case MB_TAG_LAST:
+      result = MB_TYPE_OUT_OF_RANGE;
+      break;
   }
   
   return result;
@@ -773,6 +793,9 @@
     case MB_TAG_MESH:
       result = MB_TYPE_OUT_OF_RANGE;
       break;
+    case MB_TAG_LAST:
+      result = MB_TYPE_OUT_OF_RANGE;
+      break;
   }
 
   return result;
@@ -780,10 +803,10 @@
 }
 
 MBErrorCode TagServer::get_entities_with_tag_value( const MBRange &range,
-                                                     const MBEntityType type,
-                                                     const MBTag tag_handle,
-                                                     const void* value,
-                                                     MBRange &entities ) 
+                                                    const MBEntityType type,
+                                                    const MBTag tag_handle,
+                                                    const void* value,
+                                                    MBRange &entities ) 
 {
 
   MBErrorCode result = MB_TAG_NOT_FOUND;
@@ -802,137 +825,72 @@
     case MB_TAG_MESH:
       result = MB_TYPE_OUT_OF_RANGE;
       break;
+    case MB_TAG_LAST:
+      result = MB_TYPE_OUT_OF_RANGE;
+      break;
   }
 
   return result;
   
 }
 
-MBErrorCode TagServer::get_entities_with_tag_values( MBEntityType type,
+MBErrorCode TagServer::get_entities_with_tag_values( const MBRange &input_range,
+                                                      const MBEntityType type,
                                                       const MBTag *tags,
                                                       const void* const* values,
                                                       const int num_tags,
                                                       MBRange &entities,
                                                       const int condition) 
 {
+    // range should never come in empty
+  assert(!input_range.empty());
+  if (input_range.empty()) return MB_FAILURE;
+  MBRange range = input_range;
+  
   MBErrorCode result;
-  MBRange temp1, temp2;
+  MBRange temp1;
 
   if (condition != MBInterface::INTERSECT &&
       condition != MBInterface::UNION)
     return MB_FAILURE;
 
-    // if there aren't any values we're looking for, it has to be union
-  //This doesn't make sense to me so I removed it -- J.Kraftcheck
-  //int temp_condition = (NULL == values ? MBInterface::UNION : condition);
-  
   for (unsigned int it = 0; it < (unsigned int) num_tags; it++) {
       // get all entities with this tag/value combo
 
       // running result is in entities; temp1 and temp2 are working lists
     temp1.clear();
-    temp2.clear();
 
       // get the sets with this tag/value combo in temp1
     if (NULL == values || NULL == values[it]) 
-      result = get_entities(tags[it], type, temp1);
+      result = get_entities(range, tags[it], type, temp1);
     else
-      result = get_entities_with_tag_value(type, tags[it], values[it], temp1);
+      result = get_entities_with_tag_value(range, type, tags[it], values[it], temp1);
 
       // if we're doing a running intersection and we're just starting and
       // the list comes in empty, the 1st result is the start
     if (0 == it && condition == MBInterface::INTERSECT && entities.empty()) {
-      entities = temp1;
-      if (entities.empty()) return MB_SUCCESS;
+      entities = temp1.intersect(range);
     }
 
       // else if we're doing a running intersection, intersect this result (temp1)
       // with the running result (entities) into temp2, then move that to the running
       // result (entities)
     else if (condition == MBInterface::INTERSECT) {
-      std::set_intersection(entities.begin(), entities.end(),
-                            temp1.begin(), temp1.end(),
-                            mb_range_inserter(temp2));
-      entities = temp2;
+      entities = entities.intersect(temp1);
       if (entities.empty()) return MB_SUCCESS;
-    }
 
-      // else if we're doing a union, put these results (temp1) into the running result (entities)
-      // and re-sort the running result
-    else if (condition == MBInterface::UNION) {
-      entities.merge(temp1);
+        // also restrict the range at which we look; entities has already been 
+        // intersected with range (through input to get_entities above) so just assign
+      range = entities;
     }
-  }
 
-    // running result is in entities, where it should be
-  return MB_SUCCESS;
-}
-
-MBErrorCode TagServer::get_entities_with_tag_values( const MBRange &range,
-                                                      const MBEntityType type,
-                                                      const MBTag *tags,
-                                                      const void* const* values,
-                                                      const int num_tags,
-                                                      MBRange &entities,
-                                                      const int condition) 
-{
-  MBErrorCode result;
-  MBRange temp1, temp2;
-
-  if (condition != MBInterface::INTERSECT &&
-      condition != MBInterface::UNION)
-    return MB_FAILURE;
-
-    // if there aren't any values we're looking for, it has to be union
-  //This doesn't make sense to me so I removed it -- J.Kraftcheck
-  //int temp_condition = (NULL == values ? MBInterface::UNION : condition);
-  
-  for (unsigned int it = 0; it < (unsigned int) num_tags; it++) {
-      // get all entities with this tag/value combo
-
-      // running result is in entities; temp1 and temp2 are working lists
-    temp1.clear();
-    temp2.clear();
-
-      // get the sets with this tag/value combo in temp1
-    if (NULL == values || NULL == values[it]) 
-      result = get_entities(tags[it], type, temp1);
-    else
-      result = get_entities_with_tag_value(type, tags[it], values[it], temp1);
-
-      // if we're doing a running intersection and we're just starting and
-      // the list comes in empty, the 1st result is the start
-    if (0 == it && condition == MBInterface::INTERSECT && entities.empty()) {
-      temp1 = entities;
-    }
-
-      // else if we're doing a running intersection, intersect this result (temp1)
-      // with the running result (entities) into temp2, then move that to the running
+      // else if we're doing a union, put these results (temp1) into the running 
       // result (entities)
-    else if (condition == MBInterface::INTERSECT) {
-      std::set_intersection(entities.begin(), entities.end(),
-                            temp1.begin(), temp1.end(),
-                            mb_range_inserter(temp2));
-      entities = temp2;
-      if (entities.empty()) return MB_SUCCESS;
-    }
-
-      // else if we're doing a union, put these results (temp1) into the running result (entities)
-      // and re-sort the running result
     else if (condition == MBInterface::UNION) {
       entities.merge(temp1);
     }
-
-    if (!range.empty()) {
-        // need to intersect results with what's in range
-      temp1.clear();
-      std::set_intersection(entities.begin(), entities.end(),
-                            range.begin(), range.end(),
-                            mb_range_inserter(temp1));
-    }
   }
 
-
     // running result is in entities, where it should be
   return MB_SUCCESS;
 }
@@ -965,6 +923,8 @@
       return mBitServer->get_number_entities(id, type, num_entities);
     case MB_TAG_MESH:
       return MB_TYPE_OUT_OF_RANGE;
+    case MB_TAG_LAST:
+      return MB_TYPE_OUT_OF_RANGE;
   }
   return MB_TAG_NOT_FOUND;
 }
@@ -984,6 +944,8 @@
       return mBitServer->get_number_entities(range, id, type, num_entities);
     case MB_TAG_MESH:
       return MB_TYPE_OUT_OF_RANGE;
+    case MB_TAG_LAST:
+      return MB_TYPE_OUT_OF_RANGE;
   }
   return MB_TAG_NOT_FOUND;
 }
@@ -1007,6 +969,8 @@
       break;
     case MB_TAG_MESH:
       break;
+    case MB_TAG_LAST:
+      break;
   }
 
     // add in size of entry in mTagTable
@@ -1034,6 +998,8 @@
       break;
     case MB_TAG_MESH:
       break;
+    case MB_TAG_LAST:
+      break;
   }
   
     // size of entry in mTagTable map

Modified: MOAB/trunk/TagServer.hpp
===================================================================
--- MOAB/trunk/TagServer.hpp	2007-09-12 22:59:16 UTC (rev 1270)
+++ MOAB/trunk/TagServer.hpp	2007-09-13 14:29:07 UTC (rev 1271)
@@ -220,13 +220,6 @@
                                             const void* value,
                                             MBRange &entities );
   
-  MBErrorCode get_entities_with_tag_values( MBEntityType type,
-                                             const MBTag *tags,
-                                             const void* const* values,
-                                             const int num_tags,
-                                             MBRange &entities,
-                                             const int condition);
-  
   MBErrorCode get_entities_with_tag_values( const MBRange &input_range,
                                              const MBEntityType type,
                                              const MBTag *tags,




More information about the moab-dev mailing list