[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