[MOAB-dev] r1299 - MOAB/trunk

kraftche at mcs.anl.gov kraftche at mcs.anl.gov
Fri Oct 5 17:38:30 CDT 2007


Author: kraftche
Date: 2007-10-05 17:38:30 -0500 (Fri, 05 Oct 2007)
New Revision: 1299

Modified:
   MOAB/trunk/EntitySequenceManager.cpp
   MOAB/trunk/EntitySequenceManager.hpp
   MOAB/trunk/MeshSetSequence.cpp
   MOAB/trunk/MeshSetSequence.hpp
Log:
add ability to allocate entity sets at a specific handle -- Tim needs this for parallel stuff

Modified: MOAB/trunk/EntitySequenceManager.cpp
===================================================================
--- MOAB/trunk/EntitySequenceManager.cpp	2007-10-05 14:35:34 UTC (rev 1298)
+++ MOAB/trunk/EntitySequenceManager.cpp	2007-10-05 22:38:30 UTC (rev 1299)
@@ -382,7 +382,35 @@
   return MB_SUCCESS;
 }
 
+MBErrorCode EntitySequenceManager::allocate_mesh_set( MBEntityHandle handle, unsigned flags )
+{
+  std::map<MBEntityHandle, MBEntitySequence*>::iterator seq_itr;
+  seq_itr = mSequenceMap[MBENTITYSET].lower_bound( handle );
+  if (seq_itr != mSequenceMap[MBENTITYSET].begin())
+    --seq_itr;
+  
+  for (; seq_itr != mSequenceMap[MBENTITYSET].end() && 
+         seq_itr->second->get_end_handle() < handle;
+         ++seq_itr );
+  
+  MeshSetSequence* seq;
+  if (seq_itr != mSequenceMap[MBENTITYSET].end() && 
+      seq_itr->second->get_start_handle() <= handle)
+    seq = reinterpret_cast<MeshSetSequence*>(seq_itr->second);
+  else {
+    MBEntityID new_seq_size = 4096;
+    if (seq_itr != mSequenceMap[MBENTITYSET].end()) {
+      MBEntityID diff = seq_itr->second->get_start_handle() - handle;
+      if (diff < new_seq_size)
+        new_seq_size = diff;
+    }
+    seq = new MeshSetSequence( this, handle, new_seq_size, (const unsigned*)0 );
+  }
+  
+  return seq->add_meshset( handle, flags );
+}
 
+
 MBErrorCode EntitySequenceManager::get_entities(MBEntityType type, MBRange &entities) const
 {
   
@@ -681,6 +709,71 @@
   ensure( num_tri >= 0 &&  (unsigned)num_tri == chktris .size() );
   ensure( num_hex == 0 );
   
+  // check allocation of meshsets with caller-specified handles
+  EntitySequenceManager setman( MBHandleUtils(0,1) );
+  MBEntityHandle start_handle = CREATE_HANDLE( MBENTITYSET, 1, junk );
+  // ID space: {}
+  check( setman.allocate_mesh_set( start_handle + 2, 0 ) );
+  // get current sequence
+  MBEntitySequence* b_seq_ptr;
+  check( setman.find( start_handle + 2, b_seq_ptr ) );
+  MeshSetSequence* seq_ptr = dynamic_cast<MeshSetSequence*>(b_seq_ptr);
+  check( seq_ptr->is_valid() );
+  ensure( seq_ptr->number_entities() == 1 );
+  // ID space: {3}
+  check( setman.allocate_mesh_set( start_handle + 4, 0 ) );
+  check( seq_ptr->is_valid() );
+  ensure( seq_ptr->number_entities() == 2 );
+  // ID space: {3,5}
+  check( setman.allocate_mesh_set( start_handle + 5, 0 ) );
+  check( seq_ptr->is_valid() );
+  ensure( seq_ptr->number_entities() == 3 );
+  // ID space: {3,5,6}
+  check( setman.allocate_mesh_set( start_handle + 3, 0 ) );
+  check( seq_ptr->is_valid() );
+  ensure( seq_ptr->number_entities() == 4 );
+  // ID space: {3-6}
+  // create new sequence after current one, with a single ID whole between them
+  MBEntityHandle offset_handle = seq_ptr->get_end_handle();
+  check( setman.allocate_mesh_set( offset_handle + 2, 0 ) );
+  // now fill in that whole (with a 1-entity sequence?)
+  check( setman.allocate_mesh_set( offset_handle + 1, 0 ) );
+  // make sure all sequences are valid
+  MBEntityHandle prev_handle = 0;
+  const std::map<MBEntityHandle, MBEntitySequence*>& map = *setman.entity_map( MBENTITYSET );
+  for (std::map<MBEntityHandle, MBEntitySequence*>::const_iterator mi = map.begin();
+       mi != map.end(); ++mi) {
+    seq_ptr = dynamic_cast<MeshSetSequence*>(mi->second);
+    check( seq_ptr->is_valid());
+    ensure( seq_ptr->get_start_handle() == mi->first );
+    ensure( seq_ptr->get_start_handle() > prev_handle );
+    ensure( seq_ptr->number_entities() <= seq_ptr->number_allocated() );
+    ensure( seq_ptr->number_entities() > 0 );
+    prev_handle = mi->second->get_end_handle();
+  }
+  // make sure attempt to re-allocate existing set fails
+  ensure( MB_ALREADY_ALLOCATED == setman.allocate_mesh_set( start_handle + 2, 0 ) );
+  ensure( MB_ALREADY_ALLOCATED == setman.allocate_mesh_set( start_handle + 3, 0 ) );
+  ensure( MB_ALREADY_ALLOCATED == setman.allocate_mesh_set( start_handle + 4, 0 ) );
+  ensure( MB_ALREADY_ALLOCATED == setman.allocate_mesh_set( start_handle + 5, 0 ) );
+  // some consistency checks
+  MBEntityID count;
+  check( setman.get_number_entities( MBENTITYSET, count ) );
+  ensure( 6 == count );
+  MBRange setlist;
+  check( setman.get_entities( MBENTITYSET, setlist ) );
+  MBRange setlist2;
+  setlist2.insert( start_handle + 2, start_handle + 5 );
+  setlist2.insert( offset_handle + 1, offset_handle + 2 );
+  if (setlist != setlist2) {
+    std::cout << "Expected:\n";
+    setlist2.print( std::cout );
+    std::cout << "Actual:\n";
+    setlist.print( std::cout );
+  }
+  ensure( setlist2 == setlist );
+  
+  
   return 0;
 }
 

Modified: MOAB/trunk/EntitySequenceManager.hpp
===================================================================
--- MOAB/trunk/EntitySequenceManager.hpp	2007-10-05 14:35:34 UTC (rev 1298)
+++ MOAB/trunk/EntitySequenceManager.hpp	2007-10-05 22:38:30 UTC (rev 1299)
@@ -118,6 +118,8 @@
   MBErrorCode create_mesh_set( unsigned proc_id,
                                unsigned flags,
                                MBEntityHandle& h );
+                               
+  MBErrorCode allocate_mesh_set( MBEntityHandle handle, unsigned flags );
 
   //! return a const reference to the map of sequences
   const std::map<MBEntityHandle, MBEntitySequence*>*

Modified: MOAB/trunk/MeshSetSequence.cpp
===================================================================
--- MOAB/trunk/MeshSetSequence.cpp	2007-10-05 14:35:34 UTC (rev 1298)
+++ MOAB/trunk/MeshSetSequence.cpp	2007-10-05 22:38:30 UTC (rev 1299)
@@ -83,6 +83,51 @@
   return 0;
 }
 
+
+MBErrorCode MeshSetSequence::add_meshset( MBEntityHandle handle, unsigned flags )
+{
+  if (handle < get_start_handle() || handle > get_end_handle())
+    return MB_INDEX_OUT_OF_RANGE;
+    // check and update allocated flag
+  const MBEntityID index = handle - get_start_handle();
+  if (mFreeEntities.empty() || !mFreeEntities[index])
+    return MB_ALREADY_ALLOCATED;
+  mFreeEntities[index] = false;
+  
+    // remove from linked list of free entities
+  if (mFirstFreeIndex == index) 
+    mFirstFreeIndex = next_free(index);
+  else if (next_free(mFirstFreeIndex) == index)
+    next_free(mFirstFreeIndex) = next_free(index);
+  else {
+#ifndef NDEBUG
+    int counter = 0;
+#endif
+    MBEntityID i = next_free(mFirstFreeIndex);
+    while (next_free(i) != index) {
+      assert( ++counter <= (number_allocated() - number_entities()) );
+      i = next_free(i);
+    }
+    next_free(i) = next_free(index);
+  }
+  
+    // update last-deleted index
+  if (mLastDeletedIndex == index)
+    mLastDeletedIndex = -1;
+  
+    // initialze entity set
+  allocate_set( flags, index );
+  mNumEntities++;
+  if (mNumEntities == mNumAllocated) {
+    mSequenceManager->notify_full(this);
+    std::vector<bool> empty;
+    mFreeEntities.swap( empty);
+  }
+  
+  return MB_SUCCESS;
+}
+  
+
 MBEntityHandle MeshSetSequence::add_meshset( unsigned flags )
 {
   if (mFirstFreeIndex == -1)
@@ -105,6 +150,66 @@
   return get_start_handle() + index;
 }
 
+MBErrorCode MeshSetSequence::is_valid() const
+{
+  if (mFirstFreeIndex >= number_allocated())
+    return MB_FAILURE;
+
+    // if entity sequence is full by any indicator, ensure
+    // all indicators are consistant
+  if (number_entities() == number_allocated() || mFreeEntities.empty() || mFirstFreeIndex < 0) {
+    if (number_entities() != number_allocated())
+      return MB_FAILURE;
+    if (!mFreeEntities.empty())
+      return MB_FAILURE;
+    if (mFirstFreeIndex >= 0)
+      return MB_FAILURE;
+    
+    return MB_SUCCESS;
+  }
+  
+    // make sure mFreeEntities is correctly allocated
+  if (mFreeEntities.size() != (size_t)number_allocated())
+    return MB_FAILURE;
+  
+    // count number of unallocated entities
+  size_t count = 0;
+  for (size_t i = 0; i < mFreeEntities.size(); ++i)
+    if (mFreeEntities[i])
+      ++count;
+  
+    // check number of free entities
+  if (count != (size_t)(number_allocated() - number_entities()))
+    return MB_FAILURE;
+  
+    // check linked list of free entities
+  for (MBEntityID i = mFirstFreeIndex; i != -1; i = next_free(i)) {
+    --count;
+    if (i < 0)
+      return MB_FAILURE;
+    if (i >= number_allocated())
+      return MB_FAILURE;
+    if (!mFreeEntities[i])
+      return MB_FAILURE;
+  }
+  
+    // check length of linked list
+  if (count != 0)
+    return MB_FAILURE;
+    
+    // check last deleted
+  if (mLastDeletedIndex != -1) {
+    if (mLastDeletedIndex < 0)
+      return MB_FAILURE;
+    if (mLastDeletedIndex >= number_allocated())
+      return MB_FAILURE;
+    if (!mFreeEntities[mLastDeletedIndex])
+      return MB_FAILURE;
+  }
+  
+  return MB_SUCCESS;
+}  
+
 void MeshSetSequence::free_handle( MBEntityHandle handle )
 {
   if (!is_valid_entity(handle))

Modified: MOAB/trunk/MeshSetSequence.hpp
===================================================================
--- MOAB/trunk/MeshSetSequence.hpp	2007-10-05 14:35:34 UTC (rev 1298)
+++ MOAB/trunk/MeshSetSequence.hpp	2007-10-05 22:38:30 UTC (rev 1299)
@@ -41,6 +41,7 @@
   virtual ~MeshSetSequence();
   virtual MBEntityHandle get_unused_handle();
   MBEntityHandle add_meshset( unsigned flags );
+  MBErrorCode add_meshset( MBEntityHandle handle, unsigned flags );
   virtual void free_handle( MBEntityHandle handle );
   virtual void get_entities( MBRange& entities ) const;
   virtual MBEntityID get_next_free_index( MBEntityID prev_free_index ) const;
@@ -64,6 +65,8 @@
   MBErrorCode num_parents ( MBEntityHandle of, int& number, int num_hops ) const;
   MBErrorCode num_children( MBEntityHandle of, int& number, int num_hops ) const;
   
+  MBErrorCode is_valid() const;
+  
 private:
 
   void initialize( EntitySequenceManager* seq_man,




More information about the moab-dev mailing list