[MOAB-dev] r1683 - in MOAB/trunk: . parallel

kraftche at mcs.anl.gov kraftche at mcs.anl.gov
Mon Mar 24 12:21:58 CDT 2008


Author: kraftche
Date: 2008-03-24 12:21:57 -0500 (Mon, 24 Mar 2008)
New Revision: 1683

Modified:
   MOAB/trunk/MBWriteUtil.cpp
   MOAB/trunk/MBWriteUtil.hpp
   MOAB/trunk/MBWriteUtilIface.hpp
   MOAB/trunk/RangeMap.hpp
   MOAB/trunk/WriteHDF5.cpp
   MOAB/trunk/WriteHDF5.hpp
   MOAB/trunk/parallel/WriteHDF5Parallel.cpp
Log:
Use RangeMap rather than tag data for mapping from entity handles to file 
IDs when writing .H5M files.  For most cases, this will result in a substantial
reduction in the memory required to write .h5m files.  It also removes the
limitation of 2M entities being written to a file that resuled from using
4-byte signed integer tag values for file IDs.*

For a large kD-tree decomposition of a triangle mesh, write speed increased
by about 4%.  For a large tet mesh (3.3 M tet block w/ skin triangles), 
the write speed is 40% faster.

* Some portions of the parallel writer still have 2M limits because
  MPI uses 'int' for sizes in calls such as MPI_Allgatherv and the
  code does not chunk data to work around this limitation.



Modified: MOAB/trunk/MBWriteUtil.cpp
===================================================================
--- MOAB/trunk/MBWriteUtil.cpp	2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/MBWriteUtil.cpp	2008-03-24 17:21:57 UTC (rev 1683)
@@ -404,6 +404,84 @@
   return MB_SUCCESS;
 }
 
+MBErrorCode MBWriteUtil::get_element_array(
+                                       MBRange::const_iterator iter,
+                                       const MBRange::const_iterator end,
+                                       const int vertices_per_elem,
+                                       const size_t elem_array_size, 
+                                       MBEntityHandle *const element_array )
+{
+  // check the data we got
+  if(iter == end)
+    return MB_FAILURE;
+  if(vertices_per_elem < 1)
+    return MB_FAILURE;
+  if(!element_array || elem_array_size < (unsigned)vertices_per_elem)
+    return MB_FAILURE;
+
+  // Sequence iterators
+  TypeSequenceManager::const_iterator seq_iter, seq_end;
+  
+  // loop over range, getting coordinate value
+  MBEntityType current_type = MBMAXTYPE;
+  MBEntityHandle* output_iter = element_array;
+  MBEntityHandle*const output_end = element_array + elem_array_size;
+  while (iter != end)
+  {
+      // Make sure we have the right sequence list (and get the sequence 
+      // list for the first iteration.)
+    MBEntityType type = TYPE_FROM_HANDLE(*iter);
+    if (type != current_type)
+    {
+      if (type >= MBENTITYSET || type < MBEDGE)
+        return MB_FAILURE;
+      seq_iter = mMB->sequence_manager()->entity_map(type).begin();
+      seq_end  = mMB->sequence_manager()->entity_map(type).end();
+      current_type = type;
+    }
+    
+      // Find the sqeuence containing the current handle
+    while (seq_iter != seq_end && (*seq_iter)->end_handle() < *iter)
+      ++seq_iter;
+    if (seq_iter == seq_end || *iter < (*seq_iter)->start_handle())
+      return MB_FAILURE;
+ 
+      // get the connectivity array
+    MBEntityHandle* conn_array = NULL;
+    int conn_size = static_cast<ElementSequence*>(*seq_iter)->nodes_per_element();
+    if (conn_size != vertices_per_elem)
+      return MB_FAILURE;
+    conn_array = static_cast<ElementSequence*>(*seq_iter)->get_connectivity_array();
+   
+      // Determine how much of the sequence we want.
+    MBRange::pair_iterator pair(iter);
+    MBRange::const_iterator prev(end);
+    --prev;
+    MBEntityHandle range_end = pair->second;
+    MBEntityHandle sequence_end = (*seq_iter)->end_handle();
+    MBEntityHandle end_handle = range_end > sequence_end ? sequence_end : range_end;
+    if (end_handle > *prev)
+      end_handle = *prev;
+    MBEntityHandle count = end_handle - *iter + 1;
+    
+      // Get offset in sequence to start at
+    assert( *iter >= (*seq_iter)->start_handle() );
+    MBEntityHandle offset = *iter - (*seq_iter)->start_handle();
+
+      // Make sure sufficient space in output array
+    if (output_iter + (count * conn_size) > output_end)
+      return MB_FAILURE;
+
+      // Copy connectivity into output array
+    conn_array += (conn_size * offset);
+    memcpy( output_iter, conn_array, count * conn_size * sizeof(MBEntityHandle));
+    output_iter += count * conn_size;
+    iter += count;
+  }
+
+  return MB_SUCCESS;
+}
+
 MBErrorCode MBWriteUtil::get_poly_array_size(
       MBRange::const_iterator ,
       const MBRange::const_iterator ,
@@ -638,3 +716,9 @@
   return MB_SUCCESS;
 }
 
+MBErrorCode MBWriteUtil::get_adjacencies( MBEntityHandle entity,
+                                          const MBEntityHandle*& adj_array,
+                                          int& num_adj )
+{
+  return mMB->a_entity_factory()->get_adjacencies( entity, adj_array, num_adj );
+}

Modified: MOAB/trunk/MBWriteUtil.hpp
===================================================================
--- MOAB/trunk/MBWriteUtil.hpp	2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/MBWriteUtil.hpp	2008-03-24 17:21:57 UTC (rev 1683)
@@ -128,6 +128,39 @@
       int *const element_array
       );
 
+  /** Get connectivity for elements 
+   *
+   * Get the connectivity list for a range of elements.
+   *
+   * Failure cases:
+   *  - Passed range is empty (<code>begin == end</code>).
+   *  - <code>vertices_per_elem</code> is less than one
+   *  - <code>element_array</code> is null.
+   *  - The range contains invalid handles (non-existant entities,
+   *      not an element, etc.)
+   *  - Insufficient space in passed array.
+   *
+   *\param begin        The first element handle
+   *\param end          One past the last element handle
+   *\param vertices_per_elem Number of vertices to retreive for each
+   *                    element.  If the element has more vertices, the
+   *                    element connectivity will be truncated.  If 
+   *                    <code>vertices_per_elem</code> is greater than the
+   *                    number of nodes for an eleement, the data will be
+   *                    padded with zeros.
+   *\param array_size   The length of <code>element_array</code>
+   *\param element_array The memory location at which to store the 
+   *                    connectivity list.
+   *\author Jason Kraftcheck
+   */
+  virtual MBErrorCode get_element_array(
+      MBRange::const_iterator begin,
+      const MBRange::const_iterator end,
+      const int vertices_per_elem,
+      const size_t array_size, 
+      MBEntityHandle *const element_array
+      );
+
   /** Get poly (polygon or polyhedron) connectivity size
    *\param begin  First iterator in range of poly
    *\param end    One past last in range of poly.
@@ -210,6 +243,9 @@
       std::vector<int>& adj 
   );
   
+  MBErrorCode get_adjacencies( MBEntityHandle entity,
+                               const MBEntityHandle*& adj_array,
+                               int& num_adj );
 
 
   //! tell MB there was an error when writing the mesh

Modified: MOAB/trunk/MBWriteUtilIface.hpp
===================================================================
--- MOAB/trunk/MBWriteUtilIface.hpp	2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/MBWriteUtilIface.hpp	2008-03-24 17:21:57 UTC (rev 1683)
@@ -140,7 +140,40 @@
       int *const element_array
       ) = 0;
 
+  /** Get connectivity for elements 
+   *
+   * Get the connectivity list for a range of elements.
+   *
+   * Failure cases:
+   *  - Passed range is empty (<code>begin == end</code>).
+   *  - <code>vertices_per_elem</code> is less than one
+   *  - <code>element_array</code> is null.
+   *  - The range contains invalid handles (non-existant entities,
+   *      not an element, etc.)
+   *  - Insufficient space in passed array.
+   *
+   *\param begin        The first element handle
+   *\param end          One past the last element handle
+   *\param vertices_per_elem Number of vertices to retreive for each
+   *                    element.  If the element has more vertices, the
+   *                    element connectivity will be truncated.  If 
+   *                    <code>vertices_per_elem</code> is greater than the
+   *                    number of nodes for an eleement, the data will be
+   *                    padded with zeros.
+   *\param array_size   The length of <code>element_array</code>
+   *\param element_array The memory location at which to store the 
+   *                    connectivity list.
+   *\author Jason Kraftcheck
+   */
+  virtual MBErrorCode get_element_array(
+      MBRange::const_iterator begin,
+      const MBRange::const_iterator end,
+      const int vertices_per_elem,
+      const size_t array_size, 
+      MBEntityHandle *const element_array
+      ) = 0;
 
+
   /** Get poly (polygon or polyhedron) connectivity size
    *\param begin  First iterator in range of poly
    *\param end    One past last in range of poly.
@@ -245,6 +278,10 @@
       std::vector<int>& adj 
   ) = 0;
   
+  
+  virtual MBErrorCode get_adjacencies( MBEntityHandle entity,
+                               const MBEntityHandle*& adj_array,
+                               int& num_adj ) = 0;
 
     //! if an error occured when reading the mesh, report it to MB
     //! it makes sense to have this as long as MBInterface has a write_mesh function

Modified: MOAB/trunk/RangeMap.hpp
===================================================================
--- MOAB/trunk/RangeMap.hpp	2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/RangeMap.hpp	2008-03-24 17:21:57 UTC (rev 1683)
@@ -31,7 +31,7 @@
  * for use in situations where there are relatively few insertions
  * of large contiguous ranges of values.
  */
-template <typename KeyType, typename ValType, ValType NullVal>
+template <typename KeyType, typename ValType, ValType NullVal = 0>
 class RangeMap 
 {
 public:
@@ -49,7 +49,7 @@
    * Insert mapping from [first_key, first_key+count) to [first_val, first_val+count) 
    *
    * Input range of keys many not overlap any other input range.  If it does overlap
-   * an existing range, false is returned and the internal map is not changed.
+   * an existing range, end() is returned and the internal map is not changed.
    */
   inline iterator insert( KeyType first_key, ValType first_val, KeyType count );
   
@@ -68,11 +68,21 @@
       Range b = { key, 1, NullVal }; 
       return std::lower_bound( begin(), end(), b );
     }
+  static inline iterator lower_bound( iterator s, iterator e, KeyType key )
+    { 
+      Range b = { key, 1, NullVal }; 
+      return std::lower_bound( s, e, b );
+    }
   inline iterator upper_bound( KeyType key ) const
     { 
       Range b = { key, 1, NullVal }; 
       return std::upper_bound( begin(), end(), b );
     }
+  static inline iterator upper_bound( iterator s, iterator e, KeyType key )
+    { 
+      Range b = { key, 1, NullVal }; 
+      return std::upper_bound( s, e, b );
+    }
   inline std::pair<iterator,iterator>
     equal_range( KeyType key ) const
     { 

Modified: MOAB/trunk/WriteHDF5.cpp
===================================================================
--- MOAB/trunk/WriteHDF5.cpp	2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/WriteHDF5.cpp	2008-03-24 17:21:57 UTC (rev 1683)
@@ -76,12 +76,28 @@
 
 #define WRITE_HDF5_BUFFER_SIZE (40*1024*1024)
 
-  // This is the tag used to store file offsets (file ids)
-  // during export.  It is temporary data.
-#define HDF5_ID_TAG_NAME "hdf5_id"
+static hid_t get_id_type()
+{
+  if (8 == sizeof(WriteHDF5::id_t)) {
+    if (8 == sizeof(long))  
+      return H5T_NATIVE_ULONG;
+    else 
+      return H5T_NATIVE_UINT64;
+  }
+  else if (4 == sizeof(WriteHDF5::id_t)) {
+    if (4 == sizeof(int))
+      return H5T_NATIVE_UINT;
+    else
+      return H5T_NATIVE_UINT32;
+  }
+  else {
+    assert(0);
+    return (hid_t)-1;
+  }
+}
 
-  // This is the HDF5 type for the data of the "hdf5_id" tag.
-const hid_t WriteHDF5::id_type = H5T_NATIVE_INT;
+  // This is the HDF5 type used to store file IDs
+const hid_t WriteHDF5::id_type = get_id_type();
 
   // Some macros to handle error checking.  The
   // CHK_MHDF__ERR* macros check the value of an mhdf_Status 
@@ -176,65 +192,30 @@
   return (A);                                   \
 } while(false)
 
-/** When writing tags containing MBEntityHandles to file, need to convert tag
- *  data from MBEntityHandles to file IDs.  This function does that. 
- *
- * If the handle is not valid or does not correspond to an entity that will
- * be written to the file, the file ID is set to zero.
- *\param iface MOAB instance
- *\param tag   The TAG containing file IDs for entities
- *\param data  The data buffer.  As input, an array of MBEntityHandles.  As
- *             output an array of file IDS, where the size of each integral
- *             file ID is the same as the size of MBEntityHandle.
- *\param count The number of handles in the buffer.
- *\return true if at least one of the handles is valid and will be written to
- *             the file or at least one of the handles is NULL (zero). false
- *             otherwise
- */
-static bool convert_handle_tag( MBInterface* iface, MBTag tag, void* data, size_t count )
+bool WriteHDF5::convert_handle_tag( MBEntityHandle* data, size_t count )
 {
+  assert( sizeof(MBEntityHandle) == sizeof(id_t) );
   bool some_valid = false;
-  MBErrorCode rval;
-  
-  // if same saize
-  MBEntityHandle *buffer, *end;
-  WriteHDF5::id_t* witer;
-  int step;
-  if (sizeof(MBEntityHandle) >= sizeof(WriteHDF5::id_t)) {
-    buffer = (MBEntityHandle*)data;
-    end = buffer + count;
-    witer = (WriteHDF5::id_t*)data;
-    step = 1;
-  }
-  else {
-    // iterate in reverse order if sizeof(id_t) > sizeof(MBEntityHandle)
-    buffer = (MBEntityHandle*)data + count - 1;
-    end = (MBEntityHandle*)data - 1;
-    witer = (WriteHDF5::id_t*)data + count - 1;
-    step = -1;
-  }
-  for ( ; buffer != end; buffer += step, witer += step) {
-    if (!*buffer) {
+  for (size_t i = 0; i < count; ++i) {
+    data[i] = idMap.find( data[i] );
+    if (data[i])
       some_valid = true;
-      *witer = 0;
-    }
-    else {
-      int id;
-      rval = iface->tag_get_data( tag, buffer, 1, &id );
-      if (MB_SUCCESS == rval && id > 0) {
-        some_valid = true;
-        *witer = id;
-      }
-      else {
-        *buffer = 0;
-        *witer = 0;
-      }
-    }
   }
-
   return some_valid;
 }
 
+MBErrorCode WriteHDF5::assign_ids( const MBRange& entities, id_t id )
+{
+  MBRange::const_pair_iterator pi;
+  for (pi = entities.const_pair_begin(); pi != entities.const_pair_end(); ++pi) {
+    const MBEntityHandle n = pi->second - pi->first + 1;
+    if (idMap.end() == idMap.insert( pi->first, id, n ))
+      return MB_FAILURE;
+    id += n;
+  }
+  return MB_SUCCESS;
+}
+
 const char* WriteHDF5::ExportSet::name() const
 {
   static char buffer[32];
@@ -259,8 +240,6 @@
     iFace( iface ), 
     writeUtil( 0 ), 
     filePtr( 0 ), 
-    createdIdTag(false),
-    idTag( 0 ),
     setContentsOffset( 0 ),
     setChildrenOffset( 0 ),
     setParentsOffset( 0 ),
@@ -274,7 +253,6 @@
 MBErrorCode WriteHDF5::init()
 {
   MBErrorCode rval;
-  id_t zero_int = -1;
 
   if (writeUtil) // init has already been called
     return MB_SUCCESS;
@@ -290,17 +268,9 @@
     // Get the util interface
   rval = iFace->query_interface( "MBWriteUtilIface", (void**)&writeUtil );
   CHK_MB_ERR_0(rval);
+
+  idMap.clear();
   
-    // Get the file id tag if it exists or create it otherwise.
-  rval = iFace->tag_get_handle( HDF5_ID_TAG_NAME, idTag );
-  if (MB_TAG_NOT_FOUND == rval)
-  {
-    rval = iFace->tag_create( HDF5_ID_TAG_NAME, sizeof(id_t), 
-                              MB_TAG_DENSE, idTag, &zero_int );
-    if (MB_SUCCESS == rval)
-      createdIdTag = true;
-  }
-  
   if (MB_SUCCESS != rval)
   {
     iFace->release_interface( "MBWriteUtilIFace", writeUtil );
@@ -319,6 +289,7 @@
   setSet.range.clear();
   rangeSets.clear();
   tagList.clear();
+  idMap.clear();
   return MB_SUCCESS;
 }
   
@@ -329,8 +300,6 @@
     return;
 
   iFace->release_interface( "MBWriteUtilIface", writeUtil );
-  if (createdIdTag)
-    iFace->tag_delete( idTag );
 }
 
 
@@ -422,15 +391,6 @@
     result = gather_mesh_info( passed_export_list );
     if (MB_SUCCESS != result) 
       return result;
-    
-      // Mark all entities invalid.  Later the ones we are
-      // exporting will be marked valid.  This way we can
-      // distinguish adjacent entities and such that aren't
-      // being exported.
-      // Don't to this, just set the default value to -1 when
-      // the tag is created in the init() function.
-    //result = clear_all_id_tags();
-    //if (MB_SUCCESS != result) return result;
   }
   
   //if (nodeSet.range.size() == 0)
@@ -525,30 +485,6 @@
   return MB_SUCCESS;
 }
 
-  // Initialize all file ids to -1.  We do this so that
-  // if we are writing only a part of the mesh, we can
-  // easily identify adjacencies, set contents, etc. which
-  // are not in the mesh we are writing.
-MBErrorCode WriteHDF5::clear_all_id_tags()
-{
-  id_t cleared_value = -1;
-  MBRange range;
-  for (MBEntityType type = MBVERTEX; type < MBMAXTYPE; ++type)
-  {
-    range.clear();
-    MBErrorCode rval = iFace->get_entities_by_type( 0, type, range, false );
-    CHK_MB_ERR_0(rval);
-    
-    for (MBRange::iterator itor = range.begin(); itor != range.end(); ++itor)
-    {
-      MBEntityHandle handle = *itor;
-      rval = iFace->tag_set_data( idTag, &handle, 1, &cleared_value );
-      CHK_MB_ERR_0(rval);
-    }
-  }
-  return MB_SUCCESS;
-}
-
 MBErrorCode WriteHDF5::initialize_mesh( const MBRange ranges[5] )
 {
   MBErrorCode rval;
@@ -786,11 +722,11 @@
                                             &status );
                                             
   CHK_MHDF_ERR_0(status);
-  assert (first_id <= elems.first_id);
+  assert ((unsigned long)first_id <= elems.first_id);
   assert ((unsigned long)table_size >= elems.offset + elems.range.size());
   
   
-  id_t* buffer = (id_t*)dataBuffer;
+  MBEntityHandle* buffer = (MBEntityHandle*)dataBuffer;
   int chunk_size = bufferSize / (elems.num_nodes * sizeof(id_t));
   long offset = elems.offset;
   long remaining = elems.range.size();
@@ -804,10 +740,13 @@
     MBRange::iterator next = iter;
     next += count;
     rval = writeUtil->get_element_array( iter, next, elems.num_nodes, 
-                                         idTag, count * elems.num_nodes, buffer );
+                                         count * elems.num_nodes, buffer );
     CHK_MB_ERR_1(rval, elem_table, status);
     iter = next;
     
+    for (long i = 0; i < count*nodes_per_elem; ++i)
+      buffer[i] = idMap.find( buffer[i] );
+    
     mhdf_writeConnectivity( elem_table, offset, count, 
                             id_type, buffer, &status );
     CHK_MHDF_ERR_1(status, elem_table);
@@ -901,7 +840,7 @@
       rval = iFace->get_entities_by_handle( *iter, set_contents, false );
       CHK_MB_ERR_2C(rval, set_table, writeSetContents, content_table, status);
 
-      rval = range_to_id_list( set_contents, id_list );
+      rval = range_to_blocked_list( set_contents, id_list );
       CHK_MB_ERR_2C(rval, set_table, writeSetContents, content_table, status);
 
       assert (id_list.size() < (unsigned long)data_size);
@@ -1031,9 +970,9 @@
   return MB_SUCCESS;
 }
 
-
-MBErrorCode WriteHDF5::range_to_id_list( const MBRange& input_range,
-                                         std::vector<id_t>& output_id_list )
+/*
+MBErrorCode WriteHDF5::range_to_blocked_list( const MBRange& input_range,
+                                              std::vector<id_t>& output_id_list )
 {
   MBRange::const_iterator r_iter;
   MBRange::const_iterator const r_end = input_range.end();
@@ -1042,16 +981,9 @@
   
     // Get file IDs from handles
   output_id_list.resize( input_range.size() );
-  rval = iFace->tag_get_data( idTag, input_range, &output_id_list[0] );
-  if (MB_ENTITY_NOT_FOUND == rval) { // ignore stale handles
-    MBRange::const_iterator i;
-    std::vector<id_t>::iterator j = output_id_list.begin();
-    for (i = input_range.begin(); i != input_range.end(); ++i, ++j) 
-      if (MB_SUCCESS != iFace->tag_get_data( idTag, &*i, 1, &*j ))
-        *j = 0;
-  }
-  else
-    CHK_MB_ERR_0(rval);
+  w_iter = output_id_list.begin();
+  for (r_iter = input_range.begin(); r_iter != r_end; ++r_iter, ++w_iter) 
+    *w_iter = idMap.find( *r_iter );
   std::sort( output_id_list.begin(), output_id_list.end() );
   
     // Count the number of ranges in the id list
@@ -1104,72 +1036,140 @@
   
   return MB_SUCCESS;
 }
- 
-MBErrorCode WriteHDF5::vector_to_id_list( 
-                                 const std::vector<MBEntityHandle>& input,
-                                 std::vector<id_t>& output )
+*/
+MBErrorCode WriteHDF5::range_to_blocked_list( const MBRange& input_range,
+                                              std::vector<id_t>& output_id_list )
 {
-  id_t id;
-  MBErrorCode rval;
-  MBEntityHandle handle;
-  std::vector<MBEntityHandle>::const_iterator i_iter = input.begin();
-  const std::vector<MBEntityHandle>::const_iterator i_end = input.end();
-  output.resize(input.size());
-  std::vector<id_t>::iterator o_iter = output.begin();
-  
-  while (i_iter != i_end)
-  {
-    handle = *i_iter;
-    rval = iFace->tag_get_data( idTag, &handle, 1, &id );
-    if (MB_ENTITY_NOT_FOUND == rval) // ignore stale handles
-      id = 0;
-    else
-      CHK_MB_ERR_0(rval);
-    *o_iter = id;
-    ++o_iter;
-    ++i_iter;
+  if (input_range.empty()) {
+    output_id_list.clear();
+    return MB_SUCCESS;
   }
 
-  return MB_SUCCESS;
-}
+    // first try ranged format, but give up if we reach the 
+    // non-range format size.
+  RangeMap<MBEntityHandle,id_t>::iterator ri = idMap.begin();
+  MBRange::const_pair_iterator pi;
+  output_id_list.resize( input_range.size() );
+  std::vector<id_t>::iterator i = output_id_list.begin();
+  for (pi = input_range.const_pair_begin(); pi != input_range.const_pair_end(); ++pi) {
+    MBEntityHandle h = pi->first;
+    while (h <= pi->second) {
+      ri = idMap.lower_bound( ri, idMap.end(), h );
+      if (ri == idMap.end()) 
+        continue;
 
+      id_t n = pi->second - pi->first + 1;
+      if (n > ri->count)
+        n = ri->count;
+  
+      if (output_id_list.end() - i < 2)
+        break;
 
-template <class T> static void 
-erase_from_vector( std::vector<T>& vector, T value )
-{
-  typename std::vector<T>::iterator r_itor, w_itor;
-  const typename std::vector<T>::iterator end = vector.end();
-  unsigned count = 0;
+      id_t id = ri->value + (h - ri->begin);
+      *i = id; ++i;
+      *i = n; ++i;
+      h += n;
+    }
+  }
   
-  for (r_itor = vector.begin(); 
-       r_itor != end && *r_itor != value; 
-       ++r_itor)
-    count++;
+    // if we ran out of space, just do list format
+  if (output_id_list.end() - i < 2) {
+    range_to_id_list( input_range, &output_id_list[0] );
+    return MB_SUCCESS;
+  }
   
-  w_itor = r_itor;
-  for ( ; r_itor != end; ++r_itor)
-  {
-    if (*r_itor != value)
-    {
-      *w_itor = *r_itor;
-      ++w_itor;
-      count++;
+    // otherwise check if we can compact the list further
+  size_t r, w = 2;
+  const size_t e = i - output_id_list.begin() - 1;
+  for (r = 2; r < e; r += 2) {
+    if (output_id_list[w-2] + output_id_list[w-1] == output_id_list[r])
+      output_id_list[w-1] += output_id_list[r+1];
+    else {
+      if (w != r) {
+        output_id_list[w] = output_id_list[r];
+        output_id_list[w+1] = output_id_list[r+1];
+      }
+      w += 2;
     }
   }
+  output_id_list.resize( w );
+  assert(output_id_list.size() % 2 == 0);
   
-  vector.resize( count );
+  return MB_SUCCESS;
 }
+  
+
+MBErrorCode WriteHDF5::range_to_id_list( const MBRange& range,
+                                         id_t* array )
+{
+  MBErrorCode rval = MB_SUCCESS;
+  RangeMap<MBEntityHandle,id_t>::iterator ri = idMap.begin();
+  MBRange::const_pair_iterator pi;
+  id_t* i = array;
+  for (pi = range.const_pair_begin(); pi != range.const_pair_end(); ++pi) {
+    MBEntityHandle h = pi->first;
+    while (h <= pi->second) {
+      ri = idMap.lower_bound( ri, idMap.end(), h );
+      if (ri == idMap.end()) {
+        rval = MB_ENTITY_NOT_FOUND;
+        *i = 0; 
+        ++i;
+        ++h;
+      }
+
+      id_t n = pi->second - pi->first + 1;
+      if (n > ri->count)
+        n = ri->count;
+
+      id_t id = ri->value - (h - ri->begin);
+      for (id_t j = 0; j < n; ++i, ++j)
+        *i = id + j;
+      h += n;
+    }
+  }
+  assert( i == array + range.size() );
+  return rval;
+}
  
+MBErrorCode WriteHDF5::vector_to_id_list( 
+                                 const std::vector<MBEntityHandle>& input,
+                                 std::vector<id_t>& output,
+                                 bool remove_zeros )
+{
+  std::vector<MBEntityHandle>::const_iterator i_iter = input.begin();
+  const std::vector<MBEntityHandle>::const_iterator i_end = input.end();
+  output.resize(input.size());
+  std::vector<id_t>::iterator o_iter = output.begin();
+  for (; i_iter != i_end; ++i_iter) {
+    id_t id = idMap.find( *i_iter );
+    if (!remove_zeros || id != 0) {
+      *o_iter = id;
+      ++o_iter;
+    }
+  }
+  output.erase( o_iter, output.end() );
+    
+  return MB_SUCCESS;
+}
 
-  
 
+
 inline MBErrorCode WriteHDF5::get_adjacencies( MBEntityHandle entity,
                                         std::vector<id_t>& adj )
 {
-  MBErrorCode rval = writeUtil->get_adjacencies( entity, idTag, adj );
-  //erase_from_vector( adj, (id_t)0 );
-  erase_from_vector( adj, (id_t)-1 );
-  return rval;
+  const MBEntityHandle* adj_array;
+  int num_adj;
+  MBErrorCode rval = writeUtil->get_adjacencies( entity, adj_array, num_adj );
+  if (MB_SUCCESS != rval)
+    return rval;
+  
+  size_t j = 0;
+  adj.resize( num_adj );
+  for (int i = 0; i < num_adj; ++i) 
+    if (id_t id = idMap.find( adj_array[i] ))
+      adj[j++] = id;
+  adj.resize( j );
+  return MB_SUCCESS;
 }
 
 
@@ -1179,7 +1179,7 @@
   mhdf_Status status;
   MBRange::const_iterator iter;
   const MBRange::const_iterator end = elements.range.end();
-  std::vector<int> adj_list;
+  std::vector<id_t> adj_list;
   
   /* Count Adjacencies */
   long count = 0;
@@ -1225,14 +1225,8 @@
       count = 0;
     }
     
-    rval = iFace->tag_get_data( idTag, &*iter, 1, buffer + count );
-    if (MB_SUCCESS != rval || buffer[count] < 1)
-    {
-      mhdf_closeData( filePtr, table, &status );
-      return MB_FAILURE;
-    }
-    buffer[++count] = adj_list.size();
-    ++count;
+    buffer[count++] = idMap.find( *iter );
+    buffer[count++] = adj_list.size();
     
     assert (adj_list.size()+2 < (unsigned long)chunk_size);
     memcpy( buffer + count, &adj_list[0], adj_list.size() * sizeof(id_t) );
@@ -1473,7 +1467,7 @@
     iter = stop;
     assert(range.size() == (unsigned)count);
     
-    rval = iFace->tag_get_data( idTag, range, id_buffer );
+    rval = range_to_id_list( range, id_buffer );
     CHK_MB_ERR_0( rval );
     
       // write the data
@@ -1589,7 +1583,8 @@
     
       // Convert MBEntityHandles to file ids
     if (mb_data_type == MB_TYPE_HANDLE)
-      convert_handle_tag( iFace, idTag, tag_buffer, count * mb_size / sizeof(MBEntityHandle) );
+      convert_handle_tag( reinterpret_cast<MBEntityHandle*>(tag_buffer), 
+                          count * mb_size / sizeof(MBEntityHandle) );
     
       // write the data
     mhdf_writeSparseTagValues( tables[1], offset, count,
@@ -1673,7 +1668,8 @@
     if (mb_data_type == MB_TYPE_HANDLE) {
       assert( size < bufferSize );
       memcpy( dataBuffer, ptr, size );
-      convert_handle_tag( iFace, idTag, dataBuffer, size / sizeof(MBEntityHandle) );
+      convert_handle_tag( reinterpret_cast<MBEntityHandle*>(dataBuffer), 
+                           size / sizeof(MBEntityHandle) );
       ptr = dataBuffer;
     }
     
@@ -1799,10 +1795,6 @@
     // Get list of tags
   for (t_itor = tag_list.begin(); t_itor != tag_list.end(); ++t_itor)
   {
-      // Don't write global ID tag
-    if (*t_itor == idTag)
-      continue;
-    
       // Don't write tags that have name beginning with "__"
     result = iFace->tag_get_name( *t_itor, tagname );
     if (MB_SUCCESS != result)
@@ -1876,7 +1868,7 @@
         result = iFace->tag_get_data( handle, &*i, 1, &values[0] );
         CHK_MB_ERR_0(result);
 
-        if (convert_handle_tag( iFace, idTag, &values[0], values.size() ))
+        if (convert_handle_tag( &values[0], values.size() ))
           ++i;
         else
           i = td_iter->range.erase( i );
@@ -1927,8 +1919,9 @@
     CHK_MHDF_ERR_0(status);
     mhdf_closeData( filePtr, handle, &status );
     CHK_MHDF_ERR_0(status);
-    writeUtil->assign_ids( nodeSet.range, idTag, (id_t)first_id );
     nodeSet.first_id = (id_t)first_id;
+    rval = assign_ids( nodeSet.range, nodeSet.first_id );
+    CHK_MB_ERR_0(rval);
   }
   else {
     nodeSet.first_id = std::numeric_limits<id_t>::max();
@@ -1944,9 +1937,10 @@
                                first_id );
     CHK_MB_ERR_0(rval);
       
-    writeUtil->assign_ids( ex_itor->range, idTag, (id_t)first_id );
     ex_itor->first_id = (id_t)first_id;
     ex_itor->offset = 0;
+    rval = assign_ids( ex_itor->range, ex_itor->first_id );
+    CHK_MB_ERR_0(rval);
   }
 
     // create node adjacency table
@@ -1996,7 +1990,11 @@
     writeSets = true;
     
     rval = create_set_meta( setSet.range.size(), first_id );
-    writeUtil->assign_ids( setSet.range, idTag, (id_t)first_id );
+    CHK_MB_ERR_0(rval);
+
+    setSet.first_id = (id_t)first_id;
+    rval = assign_ids( setSet.range, setSet.first_id );
+    CHK_MB_ERR_0(rval);
     
     rval = count_set_size( setSet.range, rangeSets, contents_len, children_len, parents_len );
     CHK_MB_ERR_0(rval);
@@ -2004,7 +2002,6 @@
     rval = create_set_tables( contents_len, children_len, parents_len );
     CHK_MB_ERR_0(rval);
    
-    setSet.first_id = (id_t)first_id;
     setSet.offset = 0;
     setContentsOffset = 0;
     setChildrenOffset = 0;
@@ -2043,7 +2040,7 @@
 MBErrorCode WriteHDF5::count_adjacencies( const MBRange& set, id_t& result )
 {
   MBErrorCode rval;
-  std::vector<int> adj_list;
+  std::vector<id_t> adj_list;
   MBRange::const_iterator iter = set.begin();
   const MBRange::const_iterator end = set.end();
   result = 0;
@@ -2117,7 +2114,7 @@
       rval = iFace->get_entities_by_handle( *iter, set_contents, false );
       CHK_MB_ERR_0(rval);
       
-      rval = range_to_id_list( set_contents, set_contents_ids );
+      rval = range_to_blocked_list( set_contents, set_contents_ids );
       CHK_MB_ERR_0(rval);
       
       if (set_contents_ids.size() < (unsigned long)contents_length_set)
@@ -2367,7 +2364,8 @@
       // convert default value
     if (def_value) {
       memcpy( dataBuffer, def_value, def_val_len );
-      if (convert_handle_tag( iFace, idTag, dataBuffer, def_val_len / sizeof(MBEntityHandle) ))
+      if (convert_handle_tag( reinterpret_cast<MBEntityHandle*>(dataBuffer), 
+                              def_val_len / sizeof(MBEntityHandle) ))
         def_value = dataBuffer;
       else
         def_value = 0;
@@ -2377,7 +2375,7 @@
     if (mesh_value) {
       MBEntityHandle* ptr = reinterpret_cast<MBEntityHandle*>(dataBuffer + def_val_len);
       memcpy( ptr, mesh_value, mesh_val_len );
-      if (convert_handle_tag( iFace, idTag, ptr, mesh_val_len / sizeof(MBEntityHandle) ))
+      if (convert_handle_tag( ptr, mesh_val_len / sizeof(MBEntityHandle) ))
         mesh_value = ptr;
       else
         mesh_value = 0;

Modified: MOAB/trunk/WriteHDF5.hpp
===================================================================
--- MOAB/trunk/WriteHDF5.hpp	2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/WriteHDF5.hpp	2008-03-24 17:21:57 UTC (rev 1683)
@@ -28,6 +28,7 @@
 #include "MBForward.hpp"
 #include "MBRange.hpp"
 #include "MBWriterIface.hpp"
+#include "RangeMap.hpp"
 
 class MBWriteUtilIface;
 
@@ -40,12 +41,12 @@
 
   static MBWriterIface* factory( MBInterface* );
 
-  /** The type of the global ID tag data 
+  /** The type to use for entity IDs w/in the file.
    * 
    * NOTE:  If this is changed, the value of id_type 
    *        MUST be changed accordingly.
    */
-  typedef int id_t;
+  typedef MBEntityHandle id_t;
   
   /** HDF5 type corresponding to type of id_t */
   static const hid_t id_type;
@@ -206,10 +207,8 @@
   //! The file handle from the mhdf library
   mhdf_FileHandle filePtr;
   
-  //! True if created the ID tag in init()
-  bool createdIdTag;
-  //! Handle for the ID tag.
-  MBTag idTag;
+  //! Map from entity handles to file IDs
+  RangeMap<MBEntityHandle,id_t> idMap;
   
   //! The list elements to export.
   std::list<ExportSet> exportList;
@@ -250,9 +249,6 @@
 
   MBErrorCode init();
 
-  //! Zero the ID tag on all entities in the mesh.
-  MBErrorCode clear_all_id_tags();
-
   //! Get information about a meshset
   MBErrorCode get_set_info( MBEntityHandle set,
                             long& num_entities,
@@ -274,6 +270,9 @@
                           unsigned long num_entities,
                           unsigned long var_len_total );
   
+  /**\brief add entities to idMap */
+  MBErrorCode assign_ids( const MBRange& entities, id_t first_id );
+  
   /** Get possibly compacted list of IDs for passed entities
    *
    * For the passed range of entities, determine if IDs
@@ -288,13 +287,32 @@
    * If the ID list is compacted, the length will be less than
    * range.size().
    */
+  MBErrorCode range_to_blocked_list( const MBRange& input_range,
+                                     std::vector<id_t>& output_id_list );
+  
+
   MBErrorCode range_to_id_list( const MBRange& input_range,
-                                std::vector<id_t>& output_id_list );
-  
+                                id_t* array );
   //! Get IDs for entities 
   MBErrorCode vector_to_id_list( const std::vector<MBEntityHandle>& input,
-                                 std::vector<id_t>& output );
+                                 std::vector<id_t>& output, 
+                                 bool remove_non_written = false );
 
+  /** When writing tags containing MBEntityHandles to file, need to convert tag
+   *  data from MBEntityHandles to file IDs.  This function does that. 
+   *
+   * If the handle is not valid or does not correspond to an entity that will
+   * be written to the file, the file ID is set to zero.
+   *\param data  The data buffer.  As input, an array of MBEntityHandles.  As
+   *             output an array of file IDS, where the size of each integral
+   *             file ID is the same as the size of MBEntityHandle.
+   *\param count The number of handles in the buffer.
+   *\return true if at least one of the handles is valid and will be written to
+   *             the file or at least one of the handles is NULL (zero). false
+   *             otherwise
+   */
+  bool convert_handle_tag( MBEntityHandle* data, size_t count );
+
   /** Get IDs of adjacent entities.
    * 
    * For all entities adjacent to the passed entity, if the

Modified: MOAB/trunk/parallel/WriteHDF5Parallel.cpp
===================================================================
--- MOAB/trunk/parallel/WriteHDF5Parallel.cpp	2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/parallel/WriteHDF5Parallel.cpp	2008-03-24 17:21:57 UTC (rev 1683)
@@ -376,16 +376,14 @@
   
   
     // For all remote mesh entities, remove them from the
-    // lists of local mesh to be exported and give them a 
-    // junk file Id of 1.  Need to specify a file ID greater
-    // than zero so the code that gathers adjacencies and 
-    // such doesn't think that the entities aren't being
-    // exported.
+    // lists of local mesh to be exported and the ID map
+    // (they will be put back into the ID map with different
+    //  IDs later.)
   for (i = 0; i < numProc; i++)
   {
     if (i == myRank) continue;
     
-    MBRange& range = remoteMesh[i];
+    const MBRange& range = remoteMesh[i];
     
     range_remove( nodeSet.range, range );
     //range_remove( setSet.range, range );
@@ -393,14 +391,9 @@
          eiter != exportList.end(); ++eiter )
       range_remove( eiter->range, range );
     
-    int id = 1;
-    for (MBRange::iterator riter = remoteMesh[i].begin(); 
-         riter != remoteMesh[i].end() && iFace->type_from_handle(*riter) != MBENTITYSET; 
-         ++riter)
-    {
-      result = iFace->tag_set_data( idTag, &*riter, 1, &id );
-      if (MB_SUCCESS != result) return result;
-    }
+    //for (MBRange::const_pair_iterator pi = range.const_pair_begin();
+    //     pi != range.const_pair_end(); ++pi) 
+    //  idMap.erase( pi->first, pi->second - pi->first + 1 );
   }
   
     // print some debug output summarizing what we've accomplished
@@ -473,19 +466,15 @@
  
   rval = create_node_table( dimension );
   if (MB_SUCCESS != rval) return rval;
+  rval = communicate_remote_ids( MBVERTEX );
+  if (MB_SUCCESS != rval) return rval;
   
-  
     /**************** Create element tables ***************/
 
   rval = negotiate_type_list();
   if (MB_SUCCESS != rval) return rval;
   rval = create_element_tables();
   if (MB_SUCCESS != rval) return rval;
-  
-
-    /**************** Comminucate all remote IDs ***********************/
-  
-  rval = communicate_remote_ids( MBVERTEX );
   for (std::list<ExportSet>::iterator ex_itor = exportList.begin(); 
        ex_itor != exportList.end(); ++ex_itor)
   {
@@ -658,9 +647,9 @@
   mhdf_Status status;
  
     // gather node counts for each processor
-  std::vector<int> node_counts(numProc);
-  int num_nodes = nodeSet.range.size();
-  result = MPI_Gather( &num_nodes, 1, MPI_INT, &node_counts[0], 1, MPI_INT, 0, MPI_COMM_WORLD );
+  std::vector<long> node_counts(numProc);
+  long num_nodes = nodeSet.range.size();
+  result = MPI_Gather( &num_nodes, 1, MPI_LONG, &node_counts[0], 1, MPI_LONG, 0, MPI_COMM_WORLD );
   assert(MPI_SUCCESS == result);
   
     // create node data in file
@@ -706,9 +695,7 @@
   assert(MPI_SUCCESS == result);
   nodeSet.offset = offset;
   
-  writeUtil->assign_ids( nodeSet.range, idTag, (id_t)(nodeSet.first_id + nodeSet.offset) );
-
-  return MB_SUCCESS;
+  return assign_ids( nodeSet.range(), nodeSet.first_id + nodeSet.offset );
 }
 
 
@@ -747,14 +734,14 @@
   exportList.sort();
   
     // Get number of types each processor has
-  int num_types = 2*exportList.size();
-  std::vector<int> counts(numProc);
-  result = MPI_Gather( &num_types, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, MPI_COMM_WORLD );
+  long num_types = 2*exportList.size();
+  std::vector<long> counts(numProc);
+  result = MPI_Gather( &num_types, 1, MPI_LONG, &counts[0], 1, MPI_LONG, 0, MPI_COMM_WORLD );
   assert(MPI_SUCCESS == result);
   
     // Get list of types on this processor
-  std::vector<int> my_types(num_types);
-  std::vector<int>::iterator viter = my_types.begin();
+  std::vector<long> my_types(num_types);
+  std::vector<long>::iterator viter = my_types.begin();
   for (std::list<ExportSet>::iterator eiter = exportList.begin();
        eiter != exportList.end(); ++eiter)
   {
@@ -768,22 +755,22 @@
   viter = my_types.begin();
   while (viter != my_types.end())
   {
-    int type = *viter; ++viter;
-    int count = *viter; ++viter;
+    long type = *viter; ++viter;
+    long count = *viter; ++viter;
     printdebug("  %s : %d\n", MBCN::EntityTypeName((MBEntityType)type), count);
   }
   END_SERIAL;
   #endif
 
     // Get list of types from each processor
-  std::vector<int> displs(numProc + 1);
+  std::vector<long> displs(numProc + 1);
   displs[0] = 0;
-  for (int i = 1; i <= numProc; ++i)
+  for (long i = 1; i <= numProc; ++i)
     displs[i] = displs[i-1] + counts[i-1];
-  int total = displs[numProc];
-  std::vector<int> alltypes(total);
-  result = MPI_Gatherv( &my_types[0], my_types.size(), MPI_INT,
-                        &alltypes[0], &counts[0], &displs[0], MPI_INT,
+  long total = displs[numProc];
+  std::vector<long> alltypes(total);
+  result = MPI_Gatherv( &my_types[0], my_types.size(), MPI_LONG,
+                        &alltypes[0], &counts[0], &displs[0], MPI_LONG,
                         0, MPI_COMM_WORLD );
   assert(MPI_SUCCESS == result);
   
@@ -807,18 +794,18 @@
   
     // Send total number of types to each processor
   total = type_list.size();
-  result = MPI_Bcast( &total, 1, MPI_INT, 0, MPI_COMM_WORLD );
+  result = MPI_Bcast( &total, 1, MPI_LONG, 0, MPI_COMM_WORLD );
   assert(MPI_SUCCESS == result);
   
     // Send list of types to each processor
-  std::vector<int> intlist(total * 2);
+  std::vector<long> intlist(total * 2);
   viter = intlist.begin();
   for (liter = type_list.begin(); liter != type_list.end(); ++liter)
   {
     *viter = liter->mbtype;  ++viter;
     *viter = liter->numnode; ++viter;
   }
-  result = MPI_Bcast( &intlist[0], 2*total, MPI_INT, 0, MPI_COMM_WORLD );
+  result = MPI_Bcast( &intlist[0], 2*total, MPI_LONG, 0, MPI_COMM_WORLD );
   assert(MPI_SUCCESS == result);
 
   #ifdef DEBUG
@@ -827,8 +814,8 @@
   viter = intlist.begin();
   while (viter != intlist.end())
   {
-    int type = *viter; ++viter;
-    int count = *viter; ++viter;
+    long type = *viter; ++viter;
+    long count = *viter; ++viter;
     printdebug("  %s : %d\n", MBCN::EntityTypeName((MBEntityType)type), count);
   }
   END_SERIAL;
@@ -838,10 +825,10 @@
     // range of entities to export.
   std::list<ExportSet>::iterator ex_iter = exportList.begin();
   viter = intlist.begin();
-  for (int i = 0; i < total; ++i)
+  for (long i = 0; i < total; ++i)
   {
-    int mbtype = *viter; ++viter;
-    int numnode = *viter; ++viter;
+    long mbtype = *viter; ++viter;
+    long numnode = *viter; ++viter;
     while (ex_iter != exportList.end() && ex_iter->type < mbtype)
       ++ex_iter;
     
@@ -939,7 +926,7 @@
   {
     ex_iter->first_id = *(viter++);
     id_t myfirst = (id_t)(ex_iter->first_id + ex_iter->offset);
-    rval = writeUtil->assign_ids( ex_iter->range, idTag, myfirst );
+    rval = assign_ids( ex_iter->range, myfirst );
     assert(MB_SUCCESS == rval);
   }
   
@@ -1097,12 +1084,19 @@
 }
 */
   
-
+/** Working data for group of global sets identified by an ID tag */
 struct RemoteSetData {
-  MBTag data_tag, filter_tag;
-  int filter_value;
-  MBRange range;
-  std::vector<int> counts, displs, all_values, local_values;
+  MBTag data_tag;    //!< The ID tag for matching sets across processors
+  MBTag filter_tag;  //!< Optional tag to filter on (e.g. geometric dimension)
+  int filter_value;  //!< Value of filter_tag for this group
+  MBRange range;     //!< Set handles with data_tag set (and optionally filter_tag == filter_value)
+  std::vector<int> counts;       //!< Number of sets with tag on each proc, indexed by MPI rank
+  std::vector<int> displs;       //!< Offset in all_values at which the data_tag values for
+                                 //!< each processor begin. displs[n] = sum(i from 0 to n-1)(counts[i])
+  std::vector<int> all_values;   //!< data_tag values for sets on all processors, 
+                                 //!< counts[0] values for proc 0, then counts[1] values for proc 
+                                 //!< 1, etc.
+  std::vector<int> local_values; //!< data_tag values for sets that exist on this processor
 };
 
 MBErrorCode WriteHDF5Parallel::get_remote_set_data( 
@@ -1157,7 +1151,7 @@
                                                 2,
                                                 data.range );
     if (rval != MB_SUCCESS) return rval;
-    data.range = data.range.intersect( setSet.range );
+    data.range.swap( data.range.intersect( setSet.range ) );
     range_remove( setSet.range, data.range );
   }
   
@@ -1235,7 +1229,8 @@
   assert( count == w );
   data.local_values.resize( count );
   sorted.clear(); // release storage
-    // recalculate displacements
+  
+    // recalculate displacements for updated counts
   data.displs[0] = 0;
   for (i = 1; i <= numProc; i++)
     data.displs[i] = data.displs[i-1] + data.counts[i-1];
@@ -1249,7 +1244,7 @@
     //
     // Identify which meshsets will be managed by this processor and
     // the corresponding offset in the set description table. 
-  std::map<int,int> val_id_map;
+  std::map<int,int> val_id_map; // Map from tag value to file ID for set
   int cpu = 0;
   for (i = 0; i < total; ++i)
   {
@@ -1285,7 +1280,7 @@
     std::map<int,int>::iterator p = val_id_map.find( data.local_values[i] );
     assert( p != val_id_map.end() );
     int id = p->second;
-    rval = iFace->tag_set_data( idTag, &*riter, 1, &id );
+    rval = idMap.insert( *riter, id, 1 );
     assert(MB_SUCCESS == rval);
   }
   
@@ -1369,7 +1364,7 @@
     return MB_SUCCESS;
   
     // Assign set IDs
-  writeUtil->assign_ids( setSet.range, idTag, (id_t)(setSet.first_id + setSet.offset) );
+  assign_ids( setSet.range, setSet.first_id + setSet.offset );
   for (i = 0; i < (int)remote_set_data.size(); ++i)
     fix_remote_set_ids( remote_set_data[i], setSet.first_id );
   
@@ -1788,16 +1783,21 @@
   const id_t id_diff = (id_t)(first_id - 1);
   id_t file_id;
   MBErrorCode rval;
-
-  for (MBRange::iterator iter = data.range.begin(); iter != data.range.end(); ++iter)
-  {
-    rval = iFace->tag_get_data( idTag, &*iter, 1, &file_id );
-    assert( MB_SUCCESS == rval );
-    file_id += id_diff;
-    rval = iFace->tag_set_data( idTag, &*iter, 1, &file_id );
-    assert( MB_SUCCESS == rval );
-  }
   
+  MBRange::const_iterator i;
+  std::vector<id_t> ids(data.range.size());
+  std::vector<id_t>::iterator j = ids.begin();
+  for (i = data.range.begin(); i != data.range.end(); ++i, ++j)
+    *j = idMap.find( *i ) + id_diff;
+  
+  for (MBRange::const_pair_iterator pi = data.range.const_pair_begin();
+       pi != data.range.const_pair_end(); ++pi) 
+    idMap.erase( pi->first, pi->second - pi_first + 1);
+  
+  j = ids.begin();
+  for (i = data.range.begin(); i != data.range.end(); ++i) 
+    idMap.insert( *i, *j, 1 );
+  
   return MB_SUCCESS;
 }   
 
@@ -1815,8 +1815,8 @@
       continue;  // handled by a different processor
     
       // Get offset in table at which to write data
-    int file_id;
-    rval = iFace->tag_get_data( idTag, &(iter->handle), 1, &file_id );
+    id_t file_id = idMap.find( iter->handle );
+    assert( file_id >= start_id );
     file_id -= start_id;
     
       // Get flag data
@@ -1855,15 +1855,7 @@
     remove_remote_entities( iter->handle, handle_list );
     
     id_list.clear();
-    for (unsigned int i = 0; i < handle_list.size(); ++i)
-    {
-      int id;
-      rval = iFace->tag_get_data( idTag, &handle_list[i], 1, &id );
-      assert( MB_SUCCESS == rval );
-      if (id > 0)
-        id_list.push_back(id);
-    }
-    
+    vector_to_id_list( handle_list, id_list, true );
     if (id_list.empty())
       continue;
     
@@ -1897,15 +1889,7 @@
     remove_remote_sets( iter->handle, handle_list );
     
     id_list.clear();
-    for (unsigned int i = 0; i < handle_list.size(); ++i)
-    {
-      int id;
-      rval = iFace->tag_get_data( idTag, &handle_list[i], 1, &id );
-      assert( MB_SUCCESS == rval );
-      if (id > 0)
-        id_list.push_back(id);
-    }
-    
+    vector_to_id_list( handle_list, id_list, true );
     if (!id_list.empty())
     {
       mhdf_writeSetParentsChildren( table, 
@@ -1939,15 +1923,7 @@
     remove_remote_sets( iter->handle, handle_list );
     
     id_list.clear();
-    for (unsigned int i = 0; i < handle_list.size(); ++i)
-    {
-      int id;
-      rval = iFace->tag_get_data( idTag, &handle_list[i], 1, &id );
-      assert( MB_SUCCESS == rval );
-      if (id > 0)
-        id_list.push_back(id);
-    }
-    
+    vector_to_id_list( handle_list, id_list, true );
     if (!id_list.empty())
     {
       mhdf_writeSetParentsChildren( table, 
@@ -2030,7 +2006,7 @@
 
   START_SERIAL;
   printdebug("%s ranges to communicate:\n", MBCN::EntityTypeName(type));
-  for (unsigned int xx = 0; xx != myranges.size(); xx+=2)
+  for (unsigned long xx = 0; xx != myranges.size(); xx+=2)
     printdebug("  %lu - %lu\n", myranges[xx], myranges[xx+1] );
   END_SERIAL;
   
@@ -2110,8 +2086,8 @@
       }
       assert(j < count);
       int fileid = offset + steps + (global - low);
-      rval = iFace->tag_set_data( idTag, &entity, 1, &fileid );
-      assert(MB_SUCCESS == rval);
+      RangeMap<MBEntityHandle,id_t>::iterator ri = idMap.insert( entity, fileid, 1 );
+      assert( ri != idMap.end() );
     } // for(r_iter->range)
   } // for(each processor)
   




More information about the moab-dev mailing list