[MOAB-dev] r1283 - MOAB/trunk
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Tue Sep 25 10:30:46 CDT 2007
Author: kraftche
Date: 2007-09-25 10:30:46 -0500 (Tue, 25 Sep 2007)
New Revision: 1283
Added:
MOAB/trunk/README.RefCount
Modified:
MOAB/trunk/AEntityFactory.cpp
MOAB/trunk/AEntityFactory.hpp
MOAB/trunk/EntitySequence.cpp
MOAB/trunk/EntitySequence.hpp
MOAB/trunk/EntitySequenceManager.hpp
MOAB/trunk/HigherOrderFactory.cpp
MOAB/trunk/MBCore.cpp
MOAB/trunk/MBCore.hpp
MOAB/trunk/MBMeshSet.cpp
MOAB/trunk/MBMeshSet.hpp
MOAB/trunk/MBReadUtil.cpp
MOAB/trunk/MBReadUtil.hpp
MOAB/trunk/MBReadUtilIface.hpp
MOAB/trunk/MBTest.cpp
MOAB/trunk/MeshSetSequence.cpp
MOAB/trunk/MeshSetSequence.hpp
MOAB/trunk/PolyEntitySequence.cpp
MOAB/trunk/ReadGmsh.cpp
MOAB/trunk/ReadHDF5.cpp
MOAB/trunk/ReadNCDF.cpp
MOAB/trunk/ReadSTL.cpp
MOAB/trunk/ReadVtk.cpp
MOAB/trunk/TagServer.cpp
MOAB/trunk/TagServer.hpp
MOAB/trunk/configure.in
Log:
Reference counting
Modified: MOAB/trunk/AEntityFactory.cpp
===================================================================
--- MOAB/trunk/AEntityFactory.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/AEntityFactory.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -17,7 +17,7 @@
#include "AEntityFactory.hpp"
#include "MBInternals.hpp"
-#include "MBInterface.hpp"
+#include "MBCore.hpp"
#include "MBRange.hpp"
#include "MBError.hpp"
#include "MBCN.hpp"
@@ -27,9 +27,51 @@
#include <algorithm>
#include <set>
+#ifdef MOAB_WITH_REFCOUNT
+MBErrorCode AEntityFactory::decrement_reference_count( const MBEntityHandle* arr, size_t len )
+ { return thisMB->decrement_reference_count( arr, len ); }
+MBErrorCode AEntityFactory::increment_reference_count( const MBEntityHandle* arr, size_t len )
+ { return thisMB->increment_reference_count( arr, len ); }
+MBErrorCode AEntityFactory::decrement_referenced_entities( MBEntityHandle h )
+{
+ const MBEntityHandle* adj;
+ int num_adj;
+ MBErrorCode rval = get_adjacencies( h, adj, num_adj );
+ if (MB_SUCCESS != rval || num_adj == 0)
+ return rval;
+
+ MBEntityType type = TYPE_FROM_HANDLE(h);
+ if (type == MBVERTEX)
+ return MB_SUCCESS;
+ --type;
+
+ int junk;
+ const MBEntityHandle* end
+ = std::lower_bound( adj, adj+num_adj, CREATE_HANDLE( type, 0, junk ) );
+ return decrement_reference_count( adj, end - adj );
+}
+MBErrorCode AEntityFactory::increment_referenced_entities( MBEntityHandle h )
+{
+ const MBEntityHandle* adj;
+ int num_adj;
+ MBErrorCode rval = get_adjacencies( h, adj, num_adj );
+ if (MB_SUCCESS != rval || num_adj == 0)
+ return rval;
+
+ MBEntityType type = TYPE_FROM_HANDLE(h);
+ if (type == MBVERTEX)
+ return MB_SUCCESS;
+ --type;
+
+ int junk;
+ const MBEntityHandle* end
+ = std::lower_bound( adj, adj+num_adj, CREATE_HANDLE( type, 0, junk ) );
+ return increment_reference_count( adj, end - adj );
+}
+#endif
-AEntityFactory::AEntityFactory(MBInterface *mdb)
+AEntityFactory::AEntityFactory(MBCore *mdb)
: mDensePageGroup(sizeof(void*), 0)
{
assert(NULL != mdb);
@@ -385,10 +427,10 @@
// need to make a new adjacency list first
adj_list_ptr = new MBAdjacencyVector();
result = mDensePageGroup.set_data(from_ent, &adj_list_ptr);
-
+
if (MB_SUCCESS != result) return result;
}
-
+
// get an iterator to the right spot in this sorted vector
MBAdjacencyVector::iterator adj_iter;
if (!adj_list_ptr->empty())
@@ -399,10 +441,19 @@
if ( adj_iter == adj_list_ptr->end() || to_ent != *adj_iter )
{
adj_list_ptr->insert(adj_iter, to_ent);
+#ifdef MOAB_WITH_REFCOUNT
+ if (TYPE_FROM_HANDLE(from_ent) > TYPE_FROM_HANDLE(to_ent))
+ increment_reference_count( to_ent );
+#endif
}
}
- else
+ else {
adj_list_ptr->push_back(to_ent);
+#ifdef MOAB_WITH_REFCOUNT
+ if (TYPE_FROM_HANDLE(from_ent) > TYPE_FROM_HANDLE(to_ent))
+ increment_reference_count( to_ent );
+#endif
+ }
// if both_ways is true, recursively call this function
if (true == both_ways && to_type != MBVERTEX)
@@ -413,7 +464,8 @@
//! remove an adjacency from from the base_entity.
MBErrorCode AEntityFactory::remove_adjacency(MBEntityHandle base_entity,
- MBEntityHandle adj_to_remove)
+ MBEntityHandle adj_to_remove,
+ bool update_reference_count)
{
MBErrorCode result;
@@ -435,20 +487,30 @@
// remove the specified entity from the adjacency list and truncate
// the list to the new length
- adj_list->erase(std::remove(adj_list->begin(), adj_list->end(), adj_to_remove),
- adj_list->end());
+ std::vector<MBEntityHandle>::iterator iter
+ = std::lower_bound( adj_list->begin(), adj_list->end(), adj_to_remove );
+ if (iter == adj_list->end() || *iter != adj_to_remove)
+ return MB_FAILURE;
+ adj_list->erase( iter );
+#ifdef MOAB_WITH_REFCOUNT
+ if (update_reference_count &&
+ TYPE_FROM_HANDLE(base_entity) > TYPE_FROM_HANDLE(adj_to_remove))
+ decrement_reference_count( adj_to_remove );
+#endif
+
// reset the adjacency data list
//result = thisMB->tag_set_data(adj_tag, base_entity, &adj_list);
//if (result != MB_SUCCESS)
//return result;
- return result;
+ return MB_SUCCESS;
}
//! remove all adjacencies from from the base_entity.
MBErrorCode AEntityFactory::remove_all_adjacencies(MBEntityHandle base_entity,
- const bool delete_adj_list)
+ const bool delete_adj_list,
+ bool update_reference_counts)
{
MBErrorCode result;
@@ -462,7 +524,7 @@
if (MB_SUCCESS != result && MB_MULTIPLE_ENTITIES_FOUND != result) continue;
for (MBRange::iterator rit = ents.begin(); rit != ents.end(); rit++) {
if (explicitly_adjacent(*rit, base_entity))
- remove_adjacency(*rit, base_entity);
+ remove_adjacency(*rit, base_entity, update_reference_counts);
}
}
Modified: MOAB/trunk/AEntityFactory.hpp
===================================================================
--- MOAB/trunk/AEntityFactory.hpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/AEntityFactory.hpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -26,13 +26,15 @@
typedef std::vector<MBEntityHandle> MBAdjacencyVector;
+class MBCore;
+
//! class AEntityFactory
class AEntityFactory
{
public:
//! require an MBInterface object in order to access tags on that interface
- AEntityFactory(MBInterface *mdb);
+ AEntityFactory(MBCore *mdb);
//! destructor
~AEntityFactory();
@@ -47,11 +49,13 @@
//! remove an adjacency from from the base_entity.
MBErrorCode remove_adjacency(MBEntityHandle base_entity,
- MBEntityHandle adjacency_to_remove);
+ MBEntityHandle adjacency_to_remove,
+ bool update_reference_count = true);
//! remove all adjacencies from from the base_entity.
MBErrorCode remove_all_adjacencies(MBEntityHandle base_entity,
- const bool delete_adj_list = false);
+ const bool delete_adj_list = false,
+ bool update_reference_counts = true);
//! get the elements contained by source_entity, of
//! type target_type, passing back in target_entities; if create_if_missing
@@ -140,13 +144,23 @@
unsigned long& total_entity_storage,
unsigned long& total_amortized_storage );
+#ifdef MOAB_WITH_REFCOUNT
+ MBErrorCode decrement_reference_count( const MBEntityHandle* arr, size_t len );
+ MBErrorCode increment_reference_count( const MBEntityHandle* arr, size_t len );
+ MBErrorCode decrement_reference_count( MBEntityHandle ent )
+ { return decrement_reference_count( &ent, 1 ); }
+ MBErrorCode increment_reference_count( MBEntityHandle ent )
+ { return increment_reference_count( &ent, 1 ); }
+ MBErrorCode decrement_referenced_entities( MBEntityHandle h );
+ MBErrorCode increment_referenced_entities( MBEntityHandle h );
+#endif
private:
//! private constructor to prevent the construction of a default one
AEntityFactory();
//! interface associated with this tool
- MBInterface *thisMB;
+ MBCore *thisMB;
//! adjacencies collection
DensePageGroup mDensePageGroup;
@@ -203,7 +217,7 @@
inline MBErrorCode AEntityFactory::notify_delete_entity(MBEntityHandle entity)
{
// remove any references to this entity from other entities
- return remove_all_adjacencies(entity, true);
+ return remove_all_adjacencies(entity, true, false);
}
Modified: MOAB/trunk/EntitySequence.cpp
===================================================================
--- MOAB/trunk/EntitySequence.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/EntitySequence.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -37,6 +37,9 @@
MBEntitySequence::MBEntitySequence(EntitySequenceManager* seq_manager,
MBEntityHandle start_handle, MBEntityID num_entities )
: mSequenceManager(seq_manager)
+#ifdef MOAB_WTIH_REFCOUNT
+ , mRefCount( num_entities, 0 )
+#endif
{
assert(MB_START_ID <= ID_FROM_HANDLE(start_handle));
assert(TYPE_FROM_HANDLE(start_handle) < MBMAXTYPE);
@@ -75,7 +78,13 @@
mCoords[1] = new double[num_entities];
mCoords[2] = new double[num_entities];
+#ifdef MOAB_WITH_REFCOUNT
+ mRefCount.clear();
+ mRefCount.resize( num_entities, all_handles_used ? 1 : 0 );
+#else
mFreeEntities.clear();
+#endif
+
if(all_handles_used)
{
mNumEntities = num_entities;
@@ -84,7 +93,9 @@
else
{
seq_manager->notify_not_full(this);
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities.resize(mNumAllocated, true);
+#endif
mNumEntities = 0;
mFirstFreeIndex = 0;
for(MBEntityID i=0; i<num_entities; i++)
@@ -111,7 +122,11 @@
return 0;
MBEntityHandle new_handle = mStartEntityHandle + mFirstFreeIndex;
+#ifdef MOAB_WITH_REFCOUNT
+ mRefCount[mFirstFreeIndex] = 1;
+#else
mFreeEntities[mFirstFreeIndex] = false;
+#endif
mFirstFreeIndex = reinterpret_cast<MBEntityID&>(mCoords[0][mFirstFreeIndex]);
@@ -119,8 +134,10 @@
if(mNumEntities == mNumAllocated) {
mSequenceManager->notify_full(this);
+#ifndef MOAB_WITH_REFCOUNT
std::vector<bool> empty;
mFreeEntities.swap(empty);
+#endif
}
if( mLastDeletedIndex == (MBEntityID)( new_handle - mStartEntityHandle ))
@@ -135,12 +152,21 @@
if(!is_valid_entity(handle))
return;
+#ifdef MOAB_WITH_REFCOUNT
+ if (get_reference_count(handle) != 1) // only referenced by this sequence
+ return;
+ decrement_reference_count(handle);
+#endif
+
if(mNumEntities == mNumAllocated) {
mSequenceManager->notify_not_full(this);
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities.resize( mNumAllocated, false );
+#endif
}
-
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities[handle - mStartEntityHandle] = true;
+#endif
MBEntityID prev_free_handle = -1;
const MBEntityID handle_index = handle - mStartEntityHandle;
@@ -206,13 +232,22 @@
unsigned long& allocated) const
{
unsigned long per_ent = get_memory_use((MBEntityHandle)0);
- allocated = sizeof(*this) + mFreeEntities.capacity()/8 + per_ent*number_allocated();
+ allocated = sizeof(*this) + per_ent*number_allocated();
+#ifdef MOAB_WITH_REFCOUNT
+ allocated += mRefCount.capacity() * sizeof(int);
+#else
+ allocated += mFreeEntities.capacity()/8;
+#endif
used = per_ent * number_entities();
}
unsigned long VertexEntitySequence::get_memory_use( MBEntityHandle ) const
{
+#ifdef MOAB_WITH_REFCOUNT
+ return 3 * sizeof(double) + sizeof(unsigned);
+#else
return 3 * sizeof(double);
+#endif
}
MBEntityID ElementEntitySequence::get_next_free_index( MBEntityID prev_free_index ) const
@@ -246,7 +281,13 @@
seq_manager->entity_sequence_created(this);
+#ifdef MOAB_WITH_REFCOUNT
+ mRefCount.clear();
+ mRefCount.resize( num_entities, all_handles_used ? 1 : 0 );
+#else
mFreeEntities.clear();
+#endif
+
if(all_handles_used)
{
mNumEntities = num_entities;
@@ -255,7 +296,9 @@
else
{
seq_manager->notify_not_full(this);
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities.resize( mNumAllocated, true );
+#endif
mNumEntities = 0;
mFirstFreeIndex = 0;
if (nodes_per_element)
@@ -283,7 +326,11 @@
if(mFirstFreeIndex == -1)
return 0;
+#ifdef MOAB_WITH_REFCOUNT
+ mRefCount[mFirstFreeIndex] = 1;
+#else
mFreeEntities[mFirstFreeIndex] = false;
+#endif
MBEntityHandle new_handle = mStartEntityHandle + mFirstFreeIndex;
mFirstFreeIndex = reinterpret_cast<MBEntityID&>(mElements[mFirstFreeIndex*mNodesPerElement]);
@@ -293,7 +340,9 @@
if(mNumEntities == mNumAllocated) {
mSequenceManager->notify_full(this);
std::vector<bool> empty;
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities.swap(empty);
+#endif
}
if( mLastDeletedIndex == (MBEntityID)( new_handle - mStartEntityHandle ))
@@ -307,12 +356,22 @@
if(!is_valid_entity(handle))
return;
+#ifdef MOAB_WITH_REFCOUNT
+ if (get_reference_count(handle) != 1)
+ return;
+ decrement_reference_count(handle);
+#endif
+
if(mNumEntities == mNumAllocated) {
mSequenceManager->notify_not_full(this);
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities.resize( mNumAllocated, false );
+#endif
}
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities[handle-mStartEntityHandle] = true;
+#endif
MBEntityID prev_free_index = -1;
const MBEntityID handle_index = handle - mStartEntityHandle;
@@ -379,7 +438,7 @@
assert(get_end_handle() >= split_location);
// make a new sequence
- const bool all_used = mFreeEntities.empty();
+ const bool all_used = (mNumEntities == mNumAllocated);
ElementEntitySequence* seq = new ElementEntitySequence( mSequenceManager, split_location,
get_end_handle() - split_location + 1 , mNodesPerElement, all_used);
new_sequence = seq;
@@ -405,6 +464,15 @@
assert( seq->mNumEntities == seq->mNumAllocated );
return MB_SUCCESS;
}
+
+#ifdef MOAB_WITH_REFCOUNT
+ const MBEntityHandle count = split_location - get_start_handle();
+ seq->mRefCount = mRefCount;
+ mRefCount.resize( count );
+ seq->mRefCount.erase( seq->mRefCount.begin(), seq->mRefCount.begin() + count );
+ std::vector<unsigned>(mRefCount).swap(mRefCount);
+ std::vector<unsigned>(seq->mRefCount).swap(seq->mRefCount);
+#else
//copy free handles over too
std::copy(mFreeEntities.begin()+(split_location-mStartEntityHandle),
@@ -413,21 +481,26 @@
// shrink capacity to what we need
mFreeEntities.resize(mNumAllocated);
std::vector<bool>(mFreeEntities).swap(mFreeEntities);
+#endif
-
// need to recompute : mNumEntities, mFirstFreeIndex for both sequences
mNumEntities = 0;
mFirstFreeIndex = -1;
+#ifdef MOAB_WITH_REFCOUNT
+ std::vector<unsigned>::reverse_iterator iter = mRefCount.rbegin();
+ std::vector<unsigned>::reverse_iterator end_iter = mRefCount.rend();
+#else
std::vector<bool>::reverse_iterator iter = mFreeEntities.rbegin();
std::vector<bool>::reverse_iterator end_iter = mFreeEntities.rend();
- MBEntityID index = mFreeEntities.size() - 1;
+#endif
+ MBEntityID index = mNumAllocated - 1;
MBEntityID last_index = -1;
for(; iter != end_iter; )
{
- if(*iter == true)
+ if(*iter)
{
reinterpret_cast<MBEntityID&>(mElements[index*mNodesPerElement]) = last_index;
last_index = index;
@@ -444,8 +517,10 @@
if(mNumEntities == mNumAllocated) {
mSequenceManager->notify_full(this);
+#ifndef MOAB_WITH_REFCOUNT
std::vector<bool> empty;
mFreeEntities.swap( empty );
+#endif
}
else
mSequenceManager->notify_not_full(this);
@@ -454,14 +529,20 @@
seq->mNumEntities = 0;
seq->mFirstFreeIndex = -1;
+#ifdef MOAB_WITH_REFCOUNT
+ iter = seq->mRefCount.rbegin();
+ end_iter = seq->mRefCount.rend();
+ index = seq->mRefCount.size() - 1;
+#else
iter = seq->mFreeEntities.rbegin();
end_iter = seq->mFreeEntities.rend();
index = seq->mFreeEntities.size() - 1;
+#endif
last_index = -1;
for(; iter != end_iter; )
{
- if(*iter == true)
+ if(*iter)
{
reinterpret_cast<MBEntityID&>(seq->mElements[index*mNodesPerElement]) = last_index;
last_index = index;
@@ -478,8 +559,10 @@
if(seq->mNumEntities == seq->mNumAllocated) {
mSequenceManager->notify_full(seq);
+#ifndef MOAB_WITH_REFCOUNT
std::vector<bool> empty;
seq->mFreeEntities.swap( empty );
+#endif
}
else
mSequenceManager->notify_not_full(seq);
@@ -490,10 +573,15 @@
MBErrorCode ElementEntitySequence::convert_realloc(bool& mid_edge_nodes,
- bool& mid_face_nodes, bool& mid_volume_nodes, MBCore* MB,
- MBTag delete_mark_bit )
+ bool& mid_face_nodes, bool& mid_volume_nodes, MBCore* MB
+#ifndef MOAB_WITH_REFCOUNT
+ , MBTag delete_mark_bit
+#endif
+ )
{
-
+#ifdef MOAB_WITH_REFCOUNT
+ MBRange dead_nodes;
+#endif
MBEntityType this_type = get_type();
// figure out how many nodes per element we'll end up with
@@ -546,13 +634,22 @@
old_end_handle = mElements + mNodesPerElement*mNumAllocated;
old_iter = mElements + MBCN::VerticesPerEntity(this_type);
+#ifndef MOAB_WITH_REFCOUNT
std::set<MBEntityHandle> nodes_processed;
+#endif
for(; old_iter < old_end_handle; )
{
//tag each node-to-delete with parent element entity handle and number
//of elements it is found on
for(int i=0; i<number_to_delete; i++)
{
+#ifdef MOAB_WITH_REFCOUNT
+ if (old_iter[i]) {
+ MB->decrement_reference_count( old_iter[i] );
+ if (MB->get_reference_count( old_iter[i] ) == 1)
+ dead_nodes.insert( old_iter[i] );
+ }
+#else
//see if node has been processed yet
if( old_iter[i] && nodes_processed.insert(old_iter[i]).second )
{
@@ -565,6 +662,7 @@
MB->tag_set_data(delete_mark_bit, &(old_iter[i]), 1, &bit);
}
}
+#endif
}
old_iter += mNodesPerElement;
}
@@ -598,13 +696,22 @@
if(has_mid_edge_nodes())
old_iter+=MBCN::mConnectivityMap[this_type][0].num_sub_elements;
+#ifndef MOAB_WITH_REFCOUNT
std::set<MBEntityHandle> nodes_processed;
+#endif
for(; old_iter < old_end_handle; )
{
//tag each node-to-delete with parent element entity handle and number
//of elements it is found on
for(int i=0; i<number_to_delete; i++)
{
+#ifdef MOAB_WITH_REFCOUNT
+ if (old_iter[i]) {
+ MB->decrement_reference_count( old_iter[i] );
+ if (MB->get_reference_count( old_iter[i] ) == 1)
+ dead_nodes.insert( old_iter[i] );
+ }
+#else
//see if node has been processed yet
if( old_iter[i] && nodes_processed.insert(old_iter[i]).second )
{
@@ -617,6 +724,7 @@
MB->tag_set_data(delete_mark_bit, &(old_iter[i]), 1, &bit);
}
}
+#endif
}
old_iter += mNodesPerElement;
}
@@ -653,12 +761,20 @@
for(; old_iter < old_end_handle; )
{
+#ifdef MOAB_WITH_REFCOUNT
+ if (*old_iter) {
+ MB->sequence_manager()->decrement_reference_count( *old_iter );
+ if (MB->get_reference_count( *old_iter ) == 1)
+ dead_nodes.insert( *old_iter );
+ }
+#else
if( *old_iter != 0 && tag_for_deletion( old_iter - mElements, MB ) )
{
//tag node as deletable
unsigned char bit = 0x1;
MB->tag_set_data(delete_mark_bit, &(*old_iter), 1, &bit);
}
+#endif
old_iter += mNodesPerElement;
}
@@ -677,8 +793,12 @@
mElements = new_array;
mNodesPerElement = new_nodes_per_element;
-
+
+#ifdef MOAB_WITH_REFCOUNT
+ return MB->delete_entities( dead_nodes );
+#else
return MB_SUCCESS;
+#endif
}
bool ElementEntitySequence::has_mid_edge_nodes() const
@@ -797,11 +917,37 @@
unsigned long& allocated) const
{
unsigned long per_ent = get_memory_use((MBEntityHandle)0);
- allocated = sizeof(*this) + mFreeEntities.capacity()/8 + per_ent*number_allocated();
+ allocated = sizeof(*this) + per_ent*number_allocated();
+#ifdef MOAB_WITH_REFCOUNT
+ allocated += mRefCount.capacity() * sizeof(unsigned);
+#else
+ allocated += mFreeEntities.capacity()/8;
+#endif
used = per_ent * number_entities();
}
unsigned long ElementEntitySequence::get_memory_use( MBEntityHandle ) const
{
+#ifdef MOAB_WITH_REFCOUNT
+ return sizeof(MBEntityHandle) * nodes_per_element() + sizeof(unsigned);
+#else
return sizeof(MBEntityHandle) * nodes_per_element();
+#endif
}
+
+#ifdef MOAB_WITH_REFCOUNT
+void ElementEntitySequence::decrement_all_referenced_entities( MBEntityHandle entity, AEntityFactory* f)
+{
+ const MBEntityHandle* conn;
+ int len;
+ if (MB_SUCCESS == get_connectivity( entity, conn, len ))
+ f->decrement_reference_count( conn, len );
+}
+void ElementEntitySequence::increment_all_referenced_entities( MBEntityHandle entity, AEntityFactory* f)
+{
+ const MBEntityHandle* conn;
+ int len;
+ if (MB_SUCCESS == get_connectivity( entity, conn, len ))
+ f->increment_reference_count( conn, len );
+}
+#endif
Modified: MOAB/trunk/EntitySequence.hpp
===================================================================
--- MOAB/trunk/EntitySequence.hpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/EntitySequence.hpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -42,6 +42,7 @@
class EntitySequenceManager;
class MBCore;
+class AEntityFactory;
class MBEntitySequence
{
@@ -101,6 +102,18 @@
unsigned long& allocated ) const = 0;
virtual unsigned long get_memory_use( MBEntityHandle handle ) const = 0;
+#ifdef MOAB_WITH_REFCOUNT
+ unsigned increment_reference_count( MBEntityHandle entity )
+ { return ++mRefCount[entity-get_start_handle()]; }
+ unsigned decrement_reference_count( MBEntityHandle entity )
+ { return --mRefCount[entity-get_start_handle()]; }
+ unsigned get_reference_count( MBEntityHandle entity) const
+ { return mRefCount[entity-get_start_handle()]; }
+
+ virtual void decrement_all_referenced_entities( MBEntityHandle entity, AEntityFactory* ) = 0;
+ virtual void increment_all_referenced_entities( MBEntityHandle entity, AEntityFactory* ) = 0;
+#endif
+
protected:
EntitySequenceManager* mSequenceManager;
@@ -122,8 +135,11 @@
MBEntityID mLastDeletedIndex;
//! a list of whether entities are free or not
+#ifdef MOAB_WITH_REFCOUNT
+ std::vector<unsigned> mRefCount;
+#else
std::vector<bool> mFreeEntities;
-
+#endif
};
@@ -162,6 +178,11 @@
virtual void get_memory_use( unsigned long& used, unsigned long& allocated ) const;
virtual unsigned long get_memory_use( MBEntityHandle handle ) const;
+
+#ifdef MOAB_WITH_REFCOUNT
+ virtual void decrement_all_referenced_entities( MBEntityHandle , AEntityFactory* ) {}
+ virtual void increment_all_referenced_entities( MBEntityHandle , AEntityFactory* ) {}
+#endif
private:
// coordinate arrays x,y,z
@@ -207,7 +228,11 @@
// reallocated the sequence to hold extra/less nodes, pass in what you want, and will return whether it needed
// reallocate space for those nodes
virtual MBErrorCode convert_realloc(bool& mid_edge_nodes, bool& mid_face_nodes, bool& mid_volume_nodes,
- MBCore* MB, MBTag bit_delete_mark );
+ MBCore* MB
+#ifndef MOAB_WITH_REFCOUNT
+ , MBTag bit_delete_mark
+#endif
+ );
virtual bool has_mid_edge_nodes() const;
virtual bool has_mid_face_nodes() const;
@@ -216,6 +241,10 @@
virtual void get_memory_use( unsigned long& used, unsigned long& allocated ) const;
virtual unsigned long get_memory_use( MBEntityHandle handle ) const;
+#ifdef MOAB_WITH_REFCOUNT
+ virtual void decrement_all_referenced_entities( MBEntityHandle entity, AEntityFactory* f);
+ virtual void increment_all_referenced_entities( MBEntityHandle entity, AEntityFactory* f);
+#endif
protected:
unsigned short mNodesPerElement;
@@ -232,7 +261,11 @@
inline bool MBEntitySequence::is_valid_entity(MBEntityHandle entity) const
{
+#ifdef MOAB_WITH_REFCOUNT
+ return 0 != get_reference_count(entity);
+#else
return mFreeEntities.empty() || !mFreeEntities[entity-mStartEntityHandle];
+#endif
}
Modified: MOAB/trunk/EntitySequenceManager.hpp
===================================================================
--- MOAB/trunk/EntitySequenceManager.hpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/EntitySequenceManager.hpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -43,9 +43,9 @@
#include "MBForward.hpp"
#include "MBProcConfig.hpp"
+#include "EntitySequence.hpp"
#include <map>
-class MBEntitySequence;
class HomCoord;
//! class for managing entity sequences
@@ -137,6 +137,12 @@
unsigned long& total_entity_storage,
unsigned long& total_amortized_storage ) const;
+#ifdef MOAB_WITH_REFCOUNT
+ inline unsigned increment_reference_count( MBEntityHandle handle );
+ inline unsigned decrement_reference_count( MBEntityHandle handle );
+ inline unsigned get_reference_count( MBEntityHandle handle ) const;
+#endif
+
private:
//! creates an entity sequence with a start handle and number of entities
@@ -174,6 +180,24 @@
const MBProcConfig procInfo;
};
+#ifdef MOAB_WITH_REFCOUNT
+unsigned EntitySequenceManager::increment_reference_count( MBEntityHandle handle )
+{
+ MBEntitySequence* seq;
+ return MB_SUCCESS == find( handle, seq ) ? seq->increment_reference_count(handle) : 0;
+}
+unsigned EntitySequenceManager::decrement_reference_count( MBEntityHandle handle )
+{
+ MBEntitySequence* seq;
+ return MB_SUCCESS == find( handle, seq ) ? seq->decrement_reference_count(handle) : 0;
+}
+unsigned EntitySequenceManager::get_reference_count( MBEntityHandle handle ) const
+{
+ MBEntitySequence* seq;
+ return MB_SUCCESS == find( handle, seq ) ? seq->get_reference_count(handle) : 0;
+}
#endif
+#endif
+
Modified: MOAB/trunk/HigherOrderFactory.cpp
===================================================================
--- MOAB/trunk/HigherOrderFactory.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/HigherOrderFactory.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -234,6 +234,10 @@
if(this_type == MBTRI || this_type == MBQUAD)
temp_mid_volume = false;
+#ifdef MOAB_WITH_REFCOUNT
+ seq->convert_realloc(temp_mid_edge, temp_mid_face, temp_mid_volume, mMB);
+
+#else
MBTag deletable_nodes;
mMB->tag_create("", 1, MB_TAG_BIT, deletable_nodes, NULL);
@@ -262,6 +266,7 @@
}
mMB->tag_delete(deletable_nodes);
+#endif
// create mid edge nodes if necessary
if(temp_mid_edge)
@@ -327,6 +332,9 @@
// create a new vertex at the centroid
mMB->create_vertex(sum_coords, element[new_node_index]);
+#ifdef MOAB_WITH_REFCOUNT
+ mMB->increment_reference_count( element[new_node_index] );
+#endif
if(mHONodeAddedRemoved)
mHONodeAddedRemoved->node_added(element[new_node_index], curr_handle);
@@ -413,6 +421,9 @@
mMB->create_vertex(sum_coords, element[i+num_edges+num_vertices]);
}
+#ifdef MOAB_WITH_REFCOUNT
+ mMB->increment_reference_count( element[i+num_edges+num_vertices] );
+#endif
if(mHONodeAddedRemoved)
mHONodeAddedRemoved->node_added(element[i+num_edges+num_vertices], curr_handle);
@@ -498,6 +509,9 @@
mMB->create_vertex(sum_coords, element[i+num_vertices]);
}
+#ifdef MOAB_WITH_REFCOUNT
+ mMB->increment_reference_count( element[i+num_vertices] );
+#endif
if(mHONodeAddedRemoved)
mHONodeAddedRemoved->node_added(element[i+num_vertices], curr_handle);
Modified: MOAB/trunk/MBCore.cpp
===================================================================
--- MOAB/trunk/MBCore.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MBCore.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -950,13 +950,23 @@
aEntityFactory->notify_change_connectivity(
entity_handle, old_conn, connect, num_connect);
+#ifdef MOAB_WITH_REFCOUNT
+ decrement_reference_count( old_conn, num_connect );
+#endif
status = static_cast<ElementEntitySequence*>(seq)->set_connectivity(entity_handle,
connect, num_connect);
- if (status != MB_SUCCESS)
+ if (status != MB_SUCCESS) {
aEntityFactory->notify_change_connectivity(
entity_handle, connect, old_conn, num_connect);
-
+#ifdef MOAB_WITH_REFCOUNT
+ increment_reference_count( old_conn, num_connect );
+ }
+ else {
+ increment_reference_count( connect, num_connect );
+#endif
+ }
+
return status;
}
@@ -1387,22 +1397,86 @@
const int num_entities,
const void *tag_data)
{
- if (NULL == entity_handles && 0 == num_entities)
- return tagServer->set_mesh_data(tag_handle, tag_data);
+ MBErrorCode rval;
+#ifdef MOAB_WITH_REFCOUNT
+ std::vector<MBEntityHandle> old_data;
+ std::vector<MBEntityHandle> unique_handles;
+ const TagInfo* tag_info = tagServer->get_tag_info( tag_handle );
+ if(!tag_info)
+ return MB_TAG_NOT_FOUND;
+ int count;
+#endif
+ if (NULL == entity_handles && 0 == num_entities) {
+#ifdef MOAB_WITH_REFCOUNT
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE) {
+ count = tag_info->get_size() / sizeof(MBEntityHandle);
+ old_data.resize( count );
+ rval = tagServer->get_mesh_data( tag_handle, &old_data[0] );
+ if (MB_SUCCESS == rval) {
+ rval = decrement_reference_count( &old_data[0], count );
+ if (MB_SUCCESS != rval)
+ return rval;
+ }
+ else
+ old_data.clear();
+ }
+#endif
+ rval = tagServer->set_mesh_data(tag_handle, tag_data);
+ }
+ else {
//verify handles
- MBEntitySequence* seq;
- const MBEntityHandle* iter;
- const MBEntityHandle* end = entity_handles + num_entities;
- for(iter = entity_handles; iter != end; ++iter)
- {
- if (TYPE_FROM_HANDLE(*iter) == MBENTITYSET) continue;
+ MBEntitySequence* seq;
+ const MBEntityHandle* iter;
+ const MBEntityHandle* end = entity_handles + num_entities;
+ for(iter = entity_handles; iter != end; ++iter)
+ {
+ if (TYPE_FROM_HANDLE(*iter) == MBENTITYSET) continue;
+
+ else if(sequenceManager->find(*iter, seq) != MB_SUCCESS)
+ return MB_ENTITY_NOT_FOUND;
+ }
- else if(sequenceManager->find(*iter, seq) != MB_SUCCESS)
- return MB_ENTITY_NOT_FOUND;
+#ifdef MOAB_WITH_REFCOUNT
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE) {
+ unique_handles.resize( num_entities );
+ std::copy( entity_handles, entity_handles+num_entities, unique_handles.begin() );
+ std::sort( unique_handles.begin(), unique_handles.end() );
+ unique_handles.erase( std::unique( unique_handles.begin(), unique_handles.end() ), unique_handles.end() );
+
+ count = tag_info->get_size() * unique_handles.size() / sizeof(MBEntityHandle);
+ old_data.resize( count );
+ rval = tagServer->get_mesh_data( tag_handle, &old_data[0] );
+ if (MB_SUCCESS == rval) {
+ rval = decrement_reference_count( &old_data[0], count );
+ if (MB_SUCCESS != rval)
+ return rval;
+ }
+ else
+ old_data.clear();
+ }
+#endif
+
+ rval = tagServer->set_data(tag_handle, entity_handles, num_entities, tag_data);
}
- return tagServer->set_data(tag_handle, entity_handles, num_entities, tag_data);
+#ifdef MOAB_WITH_REFCOUNT
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE) {
+ if (MB_SUCCESS == rval) {
+ if (unique_handles.size()) {
+ tag_server()->get_data( tag_handle, &unique_handles[0], unique_handles.size(), &old_data[0] );
+ rval = increment_reference_count( &old_data[0], count );
+ }
+ else {
+ rval = increment_reference_count( (const MBEntityHandle*)tag_data, count );
+ }
+ }
+ else if (!old_data.empty())
+ increment_reference_count( &old_data[0], count );
+ }
+#endif
+
+ return rval;
}
//! set the data for given EntityHandles and MBTag
@@ -1423,7 +1497,39 @@
return result;
}
- return tagServer->set_data(tag_handle, entity_handles, tag_data);
+#ifdef MOAB_WITH_REFCOUNT
+ std::vector<MBEntityHandle> old_data;
+ const TagInfo* tag_info = tagServer->get_tag_info( tag_handle );
+ if(!tag_info)
+ return MB_TAG_NOT_FOUND;
+ int count;
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE) {
+ count = tag_info->get_size() * entity_handles.size() / sizeof(MBEntityHandle);
+ old_data.resize( count );
+ result = tagServer->get_data( tag_handle, entity_handles, &old_data[0] );
+ if (MB_SUCCESS != result)
+ old_data.clear();
+ else {
+ result = decrement_reference_count( &old_data[0], count );
+ if (MB_SUCCESS != result)
+ return result;
+ }
+ }
+#endif
+
+ result = tagServer->set_data(tag_handle, entity_handles, tag_data);
+
+#ifdef MOAB_WITH_REFCOUNT
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE) {
+ if (MB_SUCCESS == result)
+ result = increment_reference_count( (const MBEntityHandle*)tag_data, count );
+ else if (!old_data.empty())
+ increment_reference_count( &old_data[0], count );
+ }
+#endif
+
+ return result;
+
}
//! adds a sparse tag for this specific EntityHandle/tag_name combination
@@ -1445,6 +1551,17 @@
const void* def_val,
bool use_existing )
{
+#ifdef MOAB_WITH_REFCOUNT
+ // don't allow a non-zero default value for handle-type tags
+ // if reference counting is enabled.
+ if (data == MB_TYPE_HANDLE && def_val) {
+ const MBEntityHandle* handles = (const MBEntityHandle*)def_val;
+ for (size_t i = 0; i < size / sizeof(MBEntityHandle); ++i)
+ if (handles[i])
+ return MB_FAILURE;
+ }
+#endif
+
MBErrorCode rval = tagServer->add_tag( name, size, storage, data, handle, def_val );
// If it is okay to use an existing tag of the same name, check that it
@@ -1484,11 +1601,32 @@
return MB_FAILURE;
MBErrorCode status = MB_SUCCESS, temp_status;
+#ifdef MOAB_WITH_REFCOUNT
+ std::vector<MBEntityHandle> old_data;
+ const TagInfo* tag_info = tagServer->get_tag_info( tag_handle );
+ if(!tag_info)
+ return MB_TAG_NOT_FOUND;
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE)
+ old_data.resize( tag_info->get_size()/sizeof(MBEntityHandle) );
+#endif
+
for (int i = 0; i < num_handles; i++) {
- if (0 == entity_handles[i])
+ if (0 == entity_handles[i]) {
+#ifdef MOAB_WITH_REFCOUNT
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE &&
+ MB_SUCCESS == tagServer->get_mesh_data( tag_handle, &old_data[0] ))
+ decrement_reference_count( &old_data[0], old_data.size() );
+#endif
temp_status = tagServer->remove_mesh_data(tag_handle);
- else
+ }
+ else {
+#ifdef MOAB_WITH_REFCOUNT
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE &&
+ MB_SUCCESS == tagServer->get_data( tag_handle, entity_handles+i, 1, &old_data[0] ))
+ decrement_reference_count( &old_data[0], old_data.size() );
+#endif
temp_status = tagServer->remove_data(tag_handle, entity_handles[i]);
+ }
if (temp_status != MB_SUCCESS) status = temp_status;
}
@@ -1502,8 +1640,22 @@
if (PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_DENSE)
return MB_FAILURE;
+#ifdef MOAB_WITH_REFCOUNT
+ std::vector<MBEntityHandle> old_data;
+ const TagInfo* tag_info = tagServer->get_tag_info( tag_handle );
+ if(!tag_info)
+ return MB_TAG_NOT_FOUND;
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE)
+ old_data.resize( tag_info->get_size()/sizeof(MBEntityHandle) );
+#endif
+
MBErrorCode status = MB_SUCCESS, temp_status;
for (MBRange::const_iterator it = entity_handles.begin(); it != entity_handles.end(); it++) {
+#ifdef MOAB_WITH_REFCOUNT
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE &&
+ MB_SUCCESS == tagServer->get_data( tag_handle, &*it, 1, &old_data[0] ))
+ decrement_reference_count( &old_data[0], old_data.size() );
+#endif
temp_status = tagServer->remove_data(tag_handle, *it);
if (temp_status != MB_SUCCESS) status = temp_status;
}
@@ -1514,6 +1666,21 @@
//! removes the tag from MB
MBErrorCode MBCore::tag_delete(MBTag tag_handle)
{
+#ifdef MOAB_WITH_REFCOUNT
+ const TagInfo* tag_info = tagServer->get_tag_info( tag_handle );
+ if(!tag_info)
+ return MB_TAG_NOT_FOUND;
+ if (tag_info->get_data_type() == MB_TYPE_HANDLE) {
+ std::vector<MBEntityHandle> tag_data;
+ for (MBEntityType t = MBVERTEX; t <= MBENTITYSET; ++t) {
+ MBRange entities;
+ tagServer->get_entities( tag_handle, t, entities );
+ tag_data.resize( entities.size() );
+ tagServer->get_data( tag_handle, entities, &tag_data[0] );
+ decrement_reference_count( &tag_data[0], tag_data.size() );
+ }
+ }
+#endif
return tag_server()->remove_tag(tag_handle);
}
@@ -1749,50 +1916,82 @@
}
+MBErrorCode MBCore::delete_entity( MBEntityHandle handle )
+{
+ MBErrorCode result;
+
+ // tell AEntityFactory that this element is going away
+ result = aEntityFactory->notify_delete_entity(handle);
+ if (MB_SUCCESS != result)
+ return result;
+
+ // reset and/or clean out data associated with this entity handle
+ result = tagServer->reset_data(handle);
+ if (MB_SUCCESS != result)
+ return result;
+
+ if (TYPE_FROM_HANDLE(handle) == MBENTITYSET) {
+ if (MBMeshSet* ptr = get_mesh_set( sequence_manager(), handle )) {
+ int j, count;
+ const MBEntityHandle* rel;
+ ptr->clear( handle, a_entity_factory() );
+ rel = ptr->get_parents( count );
+ for (j = 0; j < count; ++j)
+ remove_child_meshset( rel[j], handle );
+ rel = ptr->get_children( count );
+ for (j = 0; j < count; ++j)
+ remove_parent_meshset( rel[j],handle );
+ }
+ }
+
+ // now delete the entity
+ result = sequence_manager()->delete_entity(handle);
+ if (MB_SUCCESS != result)
+ return result;
+
+ return MB_SUCCESS;
+}
+
//! deletes an entity vector
MBErrorCode MBCore::delete_entities(const MBEntityHandle *entities,
const int num_entities)
{
+ // If reference counting is enabled, make sure all entities
+ // are unreferenced, assuming all other entities in the list
+ // are also deleted.
+#ifdef MOAB_WITH_REFCOUNT
+ std::vector<MBTag> handle_tags;
+ tag_server()->get_tags( MB_TYPE_HANDLE, handle_tags );
+
+ int ii, jj;
+ // before deleting each entity, decrement the reference count on
+ // everything that entity references.
+ for (ii = 0; ii < num_entities; ++ii)
+ if (MB_SUCCESS != decrement_all_referenced_entities( entities[ii], handle_tags ))
+ break;
+ // make sure everything that is to be deleted has a reference count
+ // of 1 (only referenced by the containing sequence).
+ if (ii == num_entities)
+ for (jj = 0; jj < num_entities; ++jj)
+ if (get_reference_count( entities[jj] ) != 1)
+ break;
+ // if we can't delete the entities, but the reference counts back
+ // to what they were before and return failure.
+ if (ii < num_entities || jj < num_entities) {
+ while (ii > 0)
+ increment_all_referenced_entities( entities[--ii], handle_tags );
+ return MB_FAILURE;
+ }
+
+#endif
+
MBErrorCode result = MB_SUCCESS, temp_result;
-
for (int i = 0; i < num_entities; i++) {
-
- // tell AEntityFactory that this element is going away
- temp_result = aEntityFactory->notify_delete_entity(entities[i]);
- if (MB_SUCCESS != temp_result) {
+ temp_result = delete_entity( entities[i] );
+ if (MB_SUCCESS != temp_result)
result = temp_result;
- continue;
- }
-
- // reset and/or clean out data associated with this entity handle
- temp_result = tagServer->reset_data(entities[i]);
- if (MB_SUCCESS != temp_result) {
- result = temp_result;
- continue;
- }
-
- if (TYPE_FROM_HANDLE(entities[i]) == MBENTITYSET) {
- if (MBMeshSet* ptr = get_mesh_set( sequence_manager(), entities[i] )) {
- int j, count;
- const MBEntityHandle* rel;
- ptr->clear( entities[i], a_entity_factory() );
- rel = ptr->get_parents( count );
- for (j = 0; j < count; ++j)
- remove_child_meshset( rel[j], entities[i] );
- rel = ptr->get_children( count );
- for (j = 0; j < count; ++j)
- remove_parent_meshset( rel[j], entities[i] );
- }
- }
-
- // now delete the entity
- temp_result = sequence_manager()->delete_entity(entities[i]);
- if (MB_SUCCESS != temp_result) {
- result = temp_result;
- continue;
- }
}
-
+
return result;
}
@@ -1800,9 +1999,36 @@
//! deletes an entity range
MBErrorCode MBCore::delete_entities(const MBRange &range)
{
+ // If reference counting is enabled, make sure all entities
+ // are unreferenced, assuming all other entities in the list
+ // are also deleted.
+#ifdef MOAB_WITH_REFCOUNT
+ std::vector<MBTag> handle_tags;
+ tag_server()->get_tags( MB_TYPE_HANDLE, handle_tags );
+
+ MBRange::const_iterator ii, jj;
+ // before deleting each entity, decrement the reference count on
+ // everything that entity references.
+ for (ii = range.begin(); ii != range.end(); ++ii)
+ if (MB_SUCCESS != decrement_all_referenced_entities( *ii, handle_tags ))
+ break;
+ // make sure everything that is to be deleted has a reference count
+ // of 1 (only referenced by the containing sequence).
+ if (ii == range.end())
+ for (jj = range.begin(); jj != range.end(); ++jj)
+ if (get_reference_count( *jj ) != 1)
+ break;
+ // if we can't delete the entities, but the reference counts back
+ // to what they were before and return failure.
+ if (ii != range.end() || jj != range.end()) {
+ while (ii != range.begin())
+ increment_all_referenced_entities( *--ii, handle_tags );
+ return MB_FAILURE;
+ }
+#endif
MBErrorCode result = MB_SUCCESS, rval;
for (MBRange::iterator i = range.begin(); i != range.end(); ++i)
- if (MB_SUCCESS != (rval = delete_entities( &*i, 1)))
+ if (MB_SUCCESS != (rval = delete_entity( *i )))
result = rval;
return rval;
}
@@ -2366,13 +2592,7 @@
MBErrorCode MBCore::add_parent_meshset( MBEntityHandle meshset,
const MBEntityHandle parent_meshset)
{
- MBMeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
- MBMeshSet* parent_ptr = get_mesh_set( sequence_manager(), parent_meshset );
- if (!set_ptr || !parent_ptr)
- return MB_ENTITY_NOT_FOUND;
-
- set_ptr->add_parent( parent_meshset );
- return MB_SUCCESS;
+ return add_parent_meshsets( meshset, &parent_meshset, 1 );
}
MBErrorCode MBCore::add_parent_meshsets( MBEntityHandle meshset,
@@ -2387,21 +2607,21 @@
if (!get_mesh_set( sequence_manager(), parents[i] ))
return MB_ENTITY_NOT_FOUND;
+#ifdef MOAB_WITH_REFCOUNT
for (int i = 0; i < count; ++i)
+ if (set_ptr->add_parent( parents[i] ))
+ increment_reference_count( parents + i, 1 );
+#else
+ for (int i = 0; i < count; ++i)
set_ptr->add_parent( parents[i] );
+#endif
return MB_SUCCESS;
}
MBErrorCode MBCore::add_child_meshset(MBEntityHandle meshset,
const MBEntityHandle child_meshset)
{
- MBMeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
- MBMeshSet* child_ptr = get_mesh_set( sequence_manager(), child_meshset );
- if (!set_ptr || !child_ptr)
- return MB_ENTITY_NOT_FOUND;
-
- set_ptr->add_child( child_meshset );
- return MB_SUCCESS;
+ return add_child_meshsets( meshset, &child_meshset, 1 );
}
MBErrorCode MBCore::add_child_meshsets( MBEntityHandle meshset,
@@ -2416,8 +2636,14 @@
if (!get_mesh_set( sequence_manager(), children[i] ))
return MB_ENTITY_NOT_FOUND;
+#ifdef MOAB_WITH_REFCOUNT
for (int i = 0; i < count; ++i)
+ if (set_ptr->add_child( children[i] ))
+ increment_reference_count( children+i, 1 );
+#else
+ for (int i = 0; i < count; ++i)
set_ptr->add_child( children[i] );
+#endif
return MB_SUCCESS;
}
@@ -2429,9 +2655,16 @@
MBMeshSet* child_ptr = get_mesh_set( sequence_manager(), child );
if (!parent_ptr || !child_ptr)
return MB_ENTITY_NOT_FOUND;
-
+
+#ifdef MOAB_WITH_REFCOUNT
+ if (parent_ptr->add_child( child ))
+ increment_reference_count( &child, 1 );
+ if (child_ptr->add_parent( parent ))
+ increment_reference_count( &parent, 1 );
+#else
parent_ptr->add_child( child );
child_ptr->add_parent( parent );
+#endif
return MB_SUCCESS;
}
@@ -2443,8 +2676,15 @@
if (!parent_ptr || !child_ptr)
return MB_ENTITY_NOT_FOUND;
+#ifdef MOAB_WITH_REFCOUNT
+ if (parent_ptr->remove_child( child ))
+ decrement_reference_count( &child, 1 );
+ if (child_ptr->remove_parent( parent ))
+ decrement_reference_count( &parent, 1 );
+#else
parent_ptr->remove_child( child );
child_ptr->remove_parent( parent );
+#endif
return MB_SUCCESS;
}
@@ -2455,7 +2695,12 @@
MBMeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
if (!set_ptr)
return MB_ENTITY_NOT_FOUND;
+#ifdef MOAB_WITH_REFCOUNT
+ if (set_ptr->remove_parent( parent_meshset ))
+ decrement_reference_count( &parent_meshset, 1 );
+#else
set_ptr->remove_parent( parent_meshset );
+#endif
return MB_SUCCESS;
}
@@ -2465,7 +2710,12 @@
MBMeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
if (!set_ptr)
return MB_ENTITY_NOT_FOUND;
+#ifdef MOAB_WITH_REFCOUNT
+ if (set_ptr->remove_child( child_meshset ))
+ decrement_reference_count( &child_meshset, 1 );
+#else
set_ptr->remove_child( child_meshset );
+#endif
return MB_SUCCESS;
}
@@ -2897,3 +3147,265 @@
tag_array, num_tags,
tag_storage, amortized_tag_storage );
}
+
+#ifdef MOAB_WITH_REFCOUNT
+
+MBErrorCode MBCore::increment_reference_count( const MBEntityHandle* array, size_t count )
+{
+ MBErrorCode result = MB_SUCCESS, tmp;
+ for (size_t i = 0; i < count; ++i) {
+ MBEntitySequence* seq;
+ tmp = sequence_manager()->find( array[i], seq );
+ if (MB_SUCCESS != tmp)
+ result = tmp;
+ else if (!seq->is_valid_entity(array[i]))
+ result = MB_ENTITY_NOT_FOUND;
+ else
+ seq->increment_reference_count( array[i] );
+ }
+ return result;
+}
+
+MBErrorCode MBCore::decrement_reference_count( const MBEntityHandle* array, size_t count )
+{
+ MBErrorCode result = MB_SUCCESS, tmp;
+ for (size_t i = 0; i < count; ++i) {
+ MBEntitySequence* seq;
+ tmp = sequence_manager()->find( array[i], seq );
+ if (MB_SUCCESS != tmp)
+ result = tmp;
+ else if (!seq->is_valid_entity(array[i]))
+ result = MB_ENTITY_NOT_FOUND;
+ else
+ seq->decrement_reference_count( array[i] );
+ }
+ return result;
+}
+
+unsigned MBCore::get_reference_count( MBEntityHandle handle )
+{
+ MBEntitySequence* seq;
+ MBErrorCode rval = sequence_manager()->find( handle, seq );
+ return MB_SUCCESS == rval ? seq->get_reference_count(handle) : 0;
+}
+
+MBErrorCode MBCore::decrement_all_referenced_entities( MBEntityHandle handle,
+ const std::vector<MBTag>& handle_tags )
+{
+ MBEntitySequence* seq;
+ MBErrorCode rval = sequence_manager()->find( handle, seq );
+ if (MB_SUCCESS != rval)
+ return rval;
+
+ seq->decrement_all_referenced_entities( handle, a_entity_factory() );
+
+ rval = a_entity_factory()->decrement_referenced_entities( handle );
+ if (MB_SUCCESS != rval) {
+ seq->increment_all_referenced_entities( handle, a_entity_factory() );
+ return rval;
+ }
+
+ std::vector<MBEntityHandle> tag_data;
+ for (std::vector<MBTag>::const_iterator i = handle_tags.begin();
+ i != handle_tags.end(); ++i) {
+ int size;
+ tag_get_size( *i, size );
+ size /= sizeof(MBEntityHandle);
+ tag_data.resize( size );
+ rval = tag_server()->get_data( *i, &handle, 1, &tag_data[0] );
+ if (MB_SUCCESS == rval)
+ decrement_reference_count( &tag_data[0], size );
+ }
+ return MB_SUCCESS;
+}
+
+
+MBErrorCode MBCore::increment_all_referenced_entities( MBEntityHandle handle,
+ const std::vector<MBTag>& handle_tags )
+{
+ MBEntitySequence* seq;
+ MBErrorCode rval = sequence_manager()->find( handle, seq );
+ if (MB_SUCCESS != rval)
+ return rval;
+
+ seq->increment_all_referenced_entities( handle, a_entity_factory() );
+
+ rval = a_entity_factory()->increment_referenced_entities( handle );
+ if (MB_SUCCESS != rval) {
+ seq->decrement_all_referenced_entities( handle, a_entity_factory() );
+ return rval;
+ }
+
+ std::vector<MBEntityHandle> tag_data;
+ for (std::vector<MBTag>::const_iterator i = handle_tags.begin();
+ i != handle_tags.end(); ++i) {
+ int size;
+ tag_get_size( *i, size );
+ size /= sizeof(MBEntityHandle);
+ tag_data.resize( size );
+ rval = tag_server()->get_data( *i, &handle, 1, &tag_data[0] );
+ if (MB_SUCCESS == rval)
+ increment_reference_count( &tag_data[0], size );
+ }
+ return MB_SUCCESS;
+}
+
+#else
+
+MBErrorCode MBCore::increment_reference_count( const MBEntityHandle* , size_t )
+{
+ abort();
+ return MB_FAILURE;
+}
+
+MBErrorCode MBCore::decrement_reference_count( const MBEntityHandle* , size_t )
+{
+ abort();
+ return MB_FAILURE;
+}
+
+unsigned MBCore::get_reference_count( MBEntityHandle )
+{
+ abort();
+ return (unsigned)-1;
+}
+
+MBErrorCode MBCore::decrement_all_referenced_entities( MBEntityHandle,
+ const std::vector<MBTag>& )
+{
+ abort();
+ return MB_FAILURE;
+}
+
+
+MBErrorCode MBCore::increment_all_referenced_entities( MBEntityHandle ,
+ const std::vector<MBTag>& )
+{
+ abort();
+ return MB_FAILURE;
+}
+
+#endif
+
+
+MBErrorCode MBCore::find_all_referencing_entities( MBEntityHandle entity,
+ MBRange& results )
+{
+ MBErrorCode rval;
+ MBRange entities;
+
+ // if entity is a vertex, check all connectivity lists
+ if (TYPE_FROM_HANDLE(entity) == MBVERTEX) {
+ for (MBEntityType t = MBEDGE; t < MBENTITYSET; ++t) {
+ if (t == MBPOLYHEDRON)
+ continue;
+ entities.clear();
+ rval = get_entities_by_type( 0, t, entities );
+ if (MB_SUCCESS != rval)
+ return rval;
+ for (MBRange::iterator i = entities.begin(); i != entities.end(); ++i) {
+ const MBEntityHandle* conn;
+ int len;
+ rval = get_connectivity( *i, conn, len );
+ if (MB_SUCCESS != rval)
+ return rval;
+ if (std::find( conn, conn+len, entity ) - conn < len)
+ results.insert( *i );
+ }
+ }
+ }
+
+ // if entity type is a face, check polyhedron connectivity
+ if (MBCN::Dimension( TYPE_FROM_HANDLE(entity) ) == 2) {
+ entities.clear();
+ rval = get_entities_by_type( 0, MBPOLYHEDRON, entities );
+ if (MB_SUCCESS != rval)
+ return rval;
+ for (MBRange::iterator i = entities.begin(); i != entities.end(); ++i) {
+ const MBEntityHandle* conn;
+ int len;
+ rval = get_connectivity( *i, conn, len );
+ if (MB_SUCCESS != rval)
+ return rval;
+ if (std::find( conn, conn+len, entity ) - conn < len)
+ results.insert( *i );
+ }
+ }
+
+ // check all adjacnecy data
+ entities.clear();
+ rval = get_entities_by_handle( 0, entities );
+ if (MB_SUCCESS != rval)
+ return rval;
+
+ for (MBRange::iterator i = entities.begin(); i != entities.end(); ++i) {
+ const MBEntityHandle* adj;
+ int len;
+ rval = a_entity_factory()->get_adjacencies( *i, adj, len );
+ if (MB_SUCCESS != rval)
+ return rval;
+
+ if (std::find( adj, adj+len, entity ) - adj < len)
+ results.insert( *i );
+ }
+
+ // check set contents
+ entities.clear();
+ rval = get_entities_by_type( 0, MBENTITYSET, entities );
+ if (MB_SUCCESS != rval)
+ return rval;
+ for (MBRange::iterator i = entities.begin(); i != entities.end(); ++i) {
+ MBRange contents;
+ rval = get_entities_by_handle( *i, contents );
+ if (contents.find( entity ) != contents.end())
+ results.insert( *i );
+ }
+
+ // if entity is a set, check set parent/child links
+ if (TYPE_FROM_HANDLE(entity) == MBENTITYSET) {
+ for (MBRange::iterator i = entities.begin(); i != entities.end(); ++i) {
+ MBRange parents, children;
+ rval = get_parent_meshsets( *i, parents );
+ if (MB_SUCCESS != rval)
+ return rval;
+ rval = get_child_meshsets( *i, children );
+ if (MB_SUCCESS != rval)
+ return rval;
+ if (parents.find(entity) != parents.end() || children.find(entity) != children.end())
+ results.insert( *i );
+ }
+ }
+
+ // check all handle tags
+ std::vector<MBTag> tags;
+ rval = tag_server()->get_tags( MB_TYPE_HANDLE, tags );
+ while (!tags.empty()) {
+ MBTag tag = tags.back();
+ tags.pop_back();
+ int size;
+ rval = tag_get_size( tag, size );
+ if (MB_SUCCESS != rval)
+ return rval;
+ std::vector<MBEntityHandle> tag_values(size/sizeof(MBEntityHandle));;
+
+ for (MBEntityType t = MBVERTEX; t <= MBENTITYSET; ++t) {
+ entities.clear();
+ rval = get_entities_by_type_and_tag( 0, t, &tag, 0, 1, entities );
+ if (MB_SUCCESS != rval)
+ return rval;
+
+ for (MBRange::iterator i = entities.begin(); i != entities.end(); ++i) {
+ rval = tag_get_data( tag, &*i, 1, &tag_values[0] );
+ if (MB_SUCCESS != rval)
+ return rval;
+ if (std::find(tag_values.begin(), tag_values.end(), entity) != tag_values.end())
+ results.insert( *i );
+ }
+ }
+ }
+
+ return MB_SUCCESS;
+}
+
+
+
Modified: MOAB/trunk/MBCore.hpp
===================================================================
--- MOAB/trunk/MBCore.hpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MBCore.hpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -950,6 +950,17 @@
virtual const MBProcConfig& proc_config() const
{ return procInfo; }
+ MBErrorCode increment_reference_count( MBEntityHandle h )
+ { return increment_reference_count( &h, 1 ); }
+ MBErrorCode decrement_reference_count( MBEntityHandle h )
+ { return decrement_reference_count( &h, 1 ); }
+ MBErrorCode increment_reference_count( const MBEntityHandle* handles, size_t size );
+ MBErrorCode decrement_reference_count( const MBEntityHandle* handles, size_t size );
+ unsigned get_reference_count( MBEntityHandle handle );
+ MBErrorCode decrement_all_referenced_entities( MBEntityHandle handle, const std::vector<MBTag>& handle_tags );
+ MBErrorCode increment_all_referenced_entities( MBEntityHandle handle, const std::vector<MBTag>& handle_tags );
+
+ MBErrorCode find_all_referencing_entities( MBEntityHandle entity, MBRange& results );
private:
void estimated_memory_use_internal( const MBRange* ents,
@@ -964,6 +975,8 @@
unsigned long* tag_storage,
unsigned long* amortized_tag_storage );
+ MBErrorCode delete_entity( MBEntityHandle handle );
+
const MBProcConfig procInfo;
//! database init and de-init routines
Modified: MOAB/trunk/MBMeshSet.cpp
===================================================================
--- MOAB/trunk/MBMeshSet.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MBMeshSet.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -274,6 +274,11 @@
mAdjFact->remove_adjacency(*iter, mEntityHandle);
}
}
+#ifdef MOAB_WITH_REFCOUNT
+ for (MBRange::iterator i = mRange.begin(); i != mRange.end(); ++i)
+ mAdjFact->decrement_reference_count( *i );
+#endif
+
mRange.clear();
return MB_SUCCESS;
}
@@ -286,7 +291,17 @@
{
int i;
for(i = 0; i < num_entities; i++)
+#ifndef MOAB_WITH_REFCOUNT
mRange.insert(entities[i]);
+#else
+ {
+ MBRange::iterator j = MBRange::lower_bound( mRange.begin(), mRange.end(), entities[i] );
+ if (j == mRange.end() || *j != entities[i]) {
+ mRange.insert( entities[i] );
+ mAdjFact->increment_reference_count( entities[i] );
+ }
+ }
+#endif
if(tracking() && mAdjFact)
{
@@ -301,8 +316,27 @@
MBEntityHandle mEntityHandle,
AEntityFactory* mAdjFact )
{
-
+#ifdef MOAB_WITH_REFCOUNT
+ if (entities.size() > mRange.size()) {
+ MBRange::const_iterator i;
+ for (i = mRange.begin(); i != mRange.end(); ++i)
+ mAdjFact->decrement_reference_count( * i );
+
+ mRange.merge( entities );
+ for (i = mRange.begin(); i != mRange.end(); ++i)
+ mAdjFact->increment_reference_count( * i );
+ }
+ else {
+ // do this in this way because we expect duplicate to be empty
+ MBRange duplicate = mRange.intersect( entities );
+ for (MBRange::const_iterator i = entities.begin(); i != entities.end(); ++i)
+ if (duplicate.find(*i) == duplicate.end())
+ mAdjFact->increment_reference_count( *i );
+ mRange.merge(entities);
+ }
+#else
mRange.merge(entities);
+#endif
if(tracking() && mAdjFact)
{
@@ -325,6 +359,9 @@
if(found != mRange.end())
{
mRange.erase(found);
+#ifdef MOAB_WITH_REFCOUNT
+ mAdjFact->decrement_reference_count( *iter );
+#endif
if(tracking() && mAdjFact)
mAdjFact->remove_adjacency(*iter, mEntityHandle);
}
@@ -345,6 +382,9 @@
if(found != mRange.end())
{
mRange.erase(found);
+#ifdef MOAB_WITH_REFCOUNT
+ mAdjFact->decrement_reference_count( entities[i] );
+#endif
if(tracking() && mAdjFact)
mAdjFact->remove_adjacency(entities[i], mEntityHandle);
}
@@ -368,6 +408,12 @@
MBEntityHandle mEntityHandle,
AEntityFactory* mAdjFact )
{
+#ifdef MOAB_WITH_REFCOUNT
+ MBRange::const_iterator i;
+ for (i = mRange.begin(); i != mRange.end(); ++i)
+ mAdjFact->decrement_reference_count( * i );
+#endif
+
MBRange other_range;
meshset_2->get_entities(other_range);
@@ -384,6 +430,11 @@
mRange.insert(*iter);
}
+#ifdef MOAB_WITH_REFCOUNT
+ for (i = mRange.begin(); i != mRange.end(); ++i)
+ mAdjFact->increment_reference_count( * i );
+#endif
+
//track owner
if(tracking() && mAdjFact)
{
@@ -417,6 +468,10 @@
MBErrorCode MBMeshSet_Vector::clear( MBEntityHandle mEntityHandle,
AEntityFactory* mAdjFact)
{
+#ifdef MOAB_WITH_REFCOUNT
+ mAdjFact->decrement_reference_count( &mVector[0], mVector.size() );
+#endif
+
if(tracking() && mAdjFact)
{
for(std::vector<MBEntityHandle>::iterator iter = mVector.begin();
@@ -453,6 +508,10 @@
mVector.resize(prev_size + num_entities);
std::copy(entities, entities+num_entities, &mVector[prev_size]);
+#ifdef MOAB_WITH_REFCOUNT
+ mAdjFact->increment_reference_count( entities, num_entities );
+#endif
+
if(tracking() && mAdjFact)
{
for(int i = 0; i < num_entities; i++)
@@ -471,6 +530,11 @@
unsigned int prev_size = mVector.size();
mVector.resize(prev_size + entities.size());
std::copy(entities.begin(), entities.end(), &mVector[prev_size]);
+
+#ifdef MOAB_WITH_REFCOUNT
+ for (MBRange::const_iterator i = entities.begin(); i != entities.end(); ++i)
+ mAdjFact->increment_reference_count( *i );
+#endif
if(tracking() && mAdjFact)
{
@@ -492,6 +556,9 @@
{
if(entities.find(*iter) != entities.end())
{
+#ifdef MOAB_WITH_REFCOUNT
+ mAdjFact->decrement_reference_count( *iter );
+#endif
if(tracking() && mAdjFact)
mAdjFact->remove_adjacency(*iter, mEntityHandle);
iter = mVector.erase(iter);
@@ -515,6 +582,9 @@
temp_iter = std::find( mVector.begin(), mVector.end(), entities[i]);
if( temp_iter != mVector.end() )
{
+#ifdef MOAB_WITH_REFCOUNT
+ mAdjFact->decrement_reference_count( *temp_iter );
+#endif
if(tracking() && mAdjFact)
mAdjFact->remove_adjacency(entities[i], mEntityHandle);
mVector.erase(temp_iter);
@@ -537,6 +607,10 @@
MBEntityHandle mEntityHandle,
AEntityFactory* mAdjFact )
{
+#ifdef MOAB_WITH_REFCOUNT
+ mAdjFact->decrement_reference_count( &mVector[0], mVector.size() );
+#endif
+
MBRange other_range;
meshset_2->get_entities(other_range);
@@ -563,6 +637,10 @@
mAdjFact->remove_adjacency(*iter, mEntityHandle);
}
+#ifdef MOAB_WITH_REFCOUNT
+ mAdjFact->increment_reference_count( &mVector[0], mVector.size() );
+#endif
+
return MB_SUCCESS;
}
@@ -581,3 +659,60 @@
+ mVector.capacity()*sizeof(MBEntityHandle);
}
+#ifdef MOAB_WITH_REFCOUNT
+
+void MBMeshSet::increment_all_referenced_entities( AEntityFactory* f )
+{
+ int count;
+ const MBEntityHandle* array;
+
+ array = get_children(count);
+ f->increment_reference_count( array, count );
+
+ array = get_parents(count);
+ f->increment_reference_count( array, count );
+
+ if (vector_based())
+ reinterpret_cast<MBMeshSet_Vector* >(this)->increment_all_referenced_entities( f );
+ else
+ reinterpret_cast<MBMeshSet_MBRange*>(this)->increment_all_referenced_entities( f );
+}
+
+void MBMeshSet::decrement_all_referenced_entities( AEntityFactory* f )
+{
+ int count;
+ const MBEntityHandle* array;
+
+ array = get_children(count);
+ f->decrement_reference_count( array, count );
+
+ array = get_parents(count);
+ f->decrement_reference_count( array, count );
+
+ if (vector_based())
+ reinterpret_cast<MBMeshSet_Vector* >(this)->decrement_all_referenced_entities( f );
+ else
+ reinterpret_cast<MBMeshSet_MBRange*>(this)->decrement_all_referenced_entities( f );
+}
+
+void MBMeshSet_Vector::increment_all_referenced_entities( AEntityFactory* f )
+{
+ f->increment_reference_count( &mVector[0], mVector.size() );
+}
+void MBMeshSet_Vector::decrement_all_referenced_entities( AEntityFactory* f )
+{
+ f->decrement_reference_count( &mVector[0], mVector.size() );
+}
+
+void MBMeshSet_MBRange::increment_all_referenced_entities( AEntityFactory* f )
+{
+ for (MBRange::const_iterator i = mRange.begin(); i != mRange.end(); ++i)
+ f->increment_reference_count( *i );
+}
+void MBMeshSet_MBRange::decrement_all_referenced_entities( AEntityFactory* f )
+{
+ for (MBRange::const_iterator i = mRange.begin(); i != mRange.end(); ++i)
+ f->decrement_reference_count( *i );
+}
+
+#endif
Modified: MOAB/trunk/MBMeshSet.hpp
===================================================================
--- MOAB/trunk/MBMeshSet.hpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MBMeshSet.hpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -208,6 +208,11 @@
inline unsigned long get_memory_use() const;
+#ifdef MOAB_WITH_REFCOUNT
+ void increment_all_referenced_entities( AEntityFactory* f );
+ void decrement_all_referenced_entities( AEntityFactory* f );
+#endif
+
protected:
unsigned long parent_child_memory_use() const;
@@ -308,7 +313,7 @@
\
inline unsigned int num_entities_by_dimension(int dimesion) const; \
\
- unsigned long get_memory_use() const;
+ unsigned long get_memory_use() const;
@@ -323,6 +328,11 @@
MESH_SET_VIRTUAL_FUNCTIONS
+#ifdef MOAB_WITH_REFCOUNT
+ void decrement_all_referenced_entities( AEntityFactory* f);
+ void increment_all_referenced_entities( AEntityFactory* f);
+#endif
+
private:
MBRange mRange;
@@ -339,6 +349,11 @@
MESH_SET_VIRTUAL_FUNCTIONS
+#ifdef MOAB_WITH_REFCOUNT
+ void decrement_all_referenced_entities( AEntityFactory* f);
+ void increment_all_referenced_entities( AEntityFactory* f);
+#endif
+
private:
static void vector_to_range( std::vector<MBEntityHandle>& vect, MBRange& range );
Modified: MOAB/trunk/MBReadUtil.cpp
===================================================================
--- MOAB/trunk/MBReadUtil.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MBReadUtil.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -36,6 +36,20 @@
unsigned MBReadUtil::parallel_rank() const
{ return mMB->proc_config().rank(); }
+
+ /** Update reference counts for connectivity links. Does nothing if
+ * not compiled with reference counting enabled.
+ */
+MBErrorCode MBReadUtil::increment_reference_count(
+ const MBEntityHandle* ent_array,
+ size_t num_ent )
+{
+#ifdef MOAB_WITH_REFCOUNT
+ return mMB->increment_reference_count( ent_array, num_ent );
+#else
+ return MB_SUCCESS;
+#endif
+}
MBErrorCode MBReadUtil::get_node_arrays(
const int /*num_arrays*/,
Modified: MOAB/trunk/MBReadUtil.hpp
===================================================================
--- MOAB/trunk/MBReadUtil.hpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MBReadUtil.hpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -88,6 +88,12 @@
int*& last_index_array,
MBEntityHandle*& connectivity_array
);
+
+ /** Update reference counts for connectivity links. Does nothing if
+ * not compiled with reference counting enabled.
+ */
+ virtual MBErrorCode increment_reference_count( const MBEntityHandle* ent_array,
+ size_t num_ent );
MBErrorCode create_entity_sets(
MBEntityID num_sets,
Modified: MOAB/trunk/MBReadUtilIface.hpp
===================================================================
--- MOAB/trunk/MBReadUtilIface.hpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MBReadUtilIface.hpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -109,6 +109,12 @@
MBEntityHandle*& connectivity_array
) = 0;
+ /** Update reference counts for connectivity links. Does nothing if
+ * not compiled with reference counting enabled.
+ */
+ virtual MBErrorCode increment_reference_count( const MBEntityHandle* ent_array,
+ size_t num_ent ) = 0;
+
virtual MBErrorCode create_entity_sets(
MBEntityID num_sets,
const unsigned* set_flags,
Modified: MOAB/trunk/MBTest.cpp
===================================================================
--- MOAB/trunk/MBTest.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MBTest.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -1333,6 +1333,13 @@
if (MB_SUCCESS != rval)
return rval;
}
+
+#ifdef MOAB_WITH_REFCOUNT
+ MBCore* core = dynamic_cast<MBCore*>(MB);
+ for (int i = 0; i < num_sets; ++i)
+ if (core->get_reference_count(sets[i]) != 1)
+ return MB_FAILURE;
+#endif
// test adding child meshsets
@@ -1362,7 +1369,7 @@
if (!compare_lists( list, sets+1, 2 ))
return MB_FAILURE;
// try adding child again
- rval = MB->add_child_meshset( sets[0], sets[1] );
+ rval = MB->add_child_meshset( sets[0], sets[2] );
if (MB_SUCCESS != rval) return rval;
list.clear();
rval = MB->get_child_meshsets( sets[0], list );
@@ -1379,7 +1386,7 @@
if (!compare_lists( list, sets+1, 3 ))
return MB_FAILURE;
// try adding child again
- rval = MB->add_child_meshset( sets[0], sets[1] );
+ rval = MB->add_child_meshset( sets[0], sets[3] );
if (MB_SUCCESS != rval) return rval;
list.clear();
rval = MB->get_child_meshsets( sets[0], list );
@@ -1395,6 +1402,14 @@
if (MB_SUCCESS != rval) return rval;
if (!compare_lists( list, sets+1, 4 ))
return MB_FAILURE;
+
+#ifdef MOAB_WITH_REFCOUNT
+ for (int i = 1; i < 5; ++i)
+ if (core->get_reference_count(sets[i]) != 2)
+ return MB_FAILURE;
+#endif
+
+
// make sure range query returns same result
std::sort( list.begin(), list.end() );
@@ -1443,6 +1458,12 @@
if (!list.empty())
return MB_FAILURE;
+#ifdef MOAB_WITH_REFCOUNT
+ for (int i = 1; i < 5; ++i)
+ if (core->get_reference_count(sets[i]) != 1)
+ return MB_FAILURE;
+#endif
+
// test adding parent meshsets
@@ -1472,7 +1493,7 @@
if (!compare_lists( list, sets+1, 2 ))
return MB_FAILURE;
// try adding parent again
- rval = MB->add_parent_meshset( sets[0], sets[1] );
+ rval = MB->add_parent_meshset( sets[0], sets[2] );
if (MB_SUCCESS != rval) return rval;
list.clear();
rval = MB->get_parent_meshsets( sets[0], list );
@@ -1489,7 +1510,7 @@
if (!compare_lists( list, sets+1, 3 ))
return MB_FAILURE;
// try adding parent again
- rval = MB->add_parent_meshset( sets[0], sets[1] );
+ rval = MB->add_parent_meshset( sets[0], sets[3] );
if (MB_SUCCESS != rval) return rval;
list.clear();
rval = MB->get_parent_meshsets( sets[0], list );
@@ -1505,6 +1526,12 @@
if (MB_SUCCESS != rval) return rval;
if (!compare_lists( list, sets+1, 4 ))
return MB_FAILURE;
+
+#ifdef MOAB_WITH_REFCOUNT
+ for (int i = 1; i < 5; ++i)
+ if (core->get_reference_count(sets[i]) != 2)
+ return MB_FAILURE;
+#endif
// make sure range query returns same result
std::sort( list.begin(), list.end() );
@@ -1552,6 +1579,12 @@
rval = MB->get_parent_meshsets( sets[0], list );
if (!list.empty())
return MB_FAILURE;
+
+#ifdef MOAB_WITH_REFCOUNT
+ for (int i = 1; i < 5; ++i)
+ if (core->get_reference_count(sets[i]) != 1)
+ return MB_FAILURE;
+#endif
// setup tests of recursive child query
@@ -1582,6 +1615,13 @@
if (MB_SUCCESS != rval) return rval;
rval = MB->add_child_meshset( sets[5], sets[7] );
if (MB_SUCCESS != rval) return rval;
+
+#ifdef MOAB_WITH_REFCOUNT
+ unsigned expref1[num_sets] = { 1, 2, 2, 2, 3, 2, 3, 3, 1, 1 };
+ for (int i = 0; i < num_sets; ++i)
+ if (core->get_reference_count(sets[i]) != expref1[i])
+ return MB_FAILURE;
+#endif
// test query at depth of 1
list.clear();
@@ -1662,7 +1702,13 @@
for (int i = 0; i < 5; ++i)
if (MB_SUCCESS != MB->num_child_meshsets(sets[i], &count) || count)
return MB_FAILURE;
-
+
+#ifdef MOAB_WITH_REFCOUNT
+ for (int i = 0; i < num_sets; ++i)
+ if (core->get_reference_count(sets[i]) != 1)
+ return MB_FAILURE;
+#endif
+
// setup tests of recursive parent query
// 6 7
// / \ / \ .
@@ -1691,6 +1737,12 @@
if (MB_SUCCESS != rval) return rval;
rval = MB->add_parent_meshset( sets[5], sets[7] );
if (MB_SUCCESS != rval) return rval;
+
+#ifdef MOAB_WITH_REFCOUNT
+ for (int i = 0; i < num_sets; ++i)
+ if (core->get_reference_count(sets[i]) != expref1[i])
+ return MB_FAILURE;
+#endif
// test query at depth of 1
list.clear();
@@ -1771,13 +1823,25 @@
for (int i = 0; i < 5; ++i)
if (MB_SUCCESS != MB->num_parent_meshsets(sets[i], &count) || count)
return MB_FAILURE;
-
+
+#ifdef MOAB_WITH_REFCOUNT
+ for (int i = 0; i < num_sets; ++i)
+ if (core->get_reference_count(sets[i]) != 1)
+ return MB_FAILURE;
+#endif
// test combined parent/child links
// test creation
rval = MB->add_parent_child( sets[9], sets[8] );
if (MB_SUCCESS != rval) return rval;
+
+#ifdef MOAB_WITH_REFCOUNT
+ if (core->get_reference_count(sets[9]) != 2 ||
+ core->get_reference_count(sets[8]) != 2)
+ return MB_FAILURE;
+#endif
+
list.clear();
rval = MB->get_child_meshsets( sets[9], list );
if (MB_SUCCESS != rval) return rval;
@@ -1790,6 +1854,7 @@
return MB_FAILURE;
// test deletion of parent/child
+#ifndef MOAB_WITH_REFCOUNT
rval = MB->add_parent_child( sets[7], sets[9] );
if (MB_SUCCESS != rval) return rval;
rval = MB->delete_entities( &sets[9], 1 );
@@ -1805,6 +1870,10 @@
// clean up remaining sets
return MB->delete_entities( sets, 9 );
+#else
+ // clean up remaining sets
+ return MB->delete_entities( sets, 10 );
+#endif
}
MBErrorCode mb_mesh_sets_set_test( MBInterface* mb )
@@ -1927,6 +1996,19 @@
if( hexes.size() + tets.size() != dim_3_range.size() )
return MB_FAILURE;
+#ifdef MOAB_WITH_REFCOUNT
+ MBCore* core = dynamic_cast<MBCore*>(MB);
+ if (core->get_reference_count( ms1 ) != 1)
+ return MB_FAILURE;
+ if (core->get_reference_count( ms2 ) != 1)
+ return MB_FAILURE;
+ if (core->get_reference_count( ms3 ) != 1)
+ return MB_FAILURE;
+ std::vector<unsigned> hex_refs;
+ for (MBRange::iterator i = hexes.begin(); i != hexes.end(); ++i)
+ hex_refs.push_back( core->get_reference_count(*i) );
+#endif
+
//put all hexes in ms1, ms2, ms3
result = MB->add_entities(ms1, hexes); //add ents in a range
if(result != MB_SUCCESS )
@@ -1942,6 +2024,19 @@
if(result != MB_SUCCESS )
return result;
+#ifdef MOAB_WITH_REFCOUNT
+ if (core->get_reference_count( ms1 ) != 1)
+ return MB_FAILURE;
+ if (core->get_reference_count( ms2 ) != 1)
+ return MB_FAILURE;
+ if (core->get_reference_count( ms3 ) != 1)
+ return MB_FAILURE;
+ std::vector<unsigned>::iterator j = hex_refs.begin();
+ for (MBRange::iterator i = hexes.begin(); i != hexes.end(); ++i, ++j)
+ if (core->get_reference_count(*i) != 3+*j)
+ return MB_FAILURE;
+#endif
+
//put all tets in ms1, ms2
if(MB->add_entities(ms1, &tets[0], tets.size()) != MB_SUCCESS ) //add ents in a vector
return MB_FAILURE; //to ordered meshset
@@ -2069,15 +2164,21 @@
MB->get_number_entities_by_handle(ms2, num_before);
vec_iter = tets.begin();
result = MB->delete_entities( &(*vec_iter), 1);
+#ifdef MOAB_WITH_REFCOUNT
+ if (result == MB_SUCCESS)
+ return MB_FAILURE;
+#else
if(result != MB_SUCCESS )
return result;
+#endif
int num_after = 0;
MB->get_number_entities_by_handle(ms2, num_after);
+#ifndef MOAB_WITH_REFCOUNT
if( num_before != num_after + 1)
return MB_FAILURE;
+#endif
-
return MB_SUCCESS;
}
@@ -2987,6 +3088,7 @@
entities.clear();
MB->get_entities_by_type(0, MBVERTEX, entities);
+
unsigned int original_num_nodes = entities.size();
entities.clear();
MB->get_entities_by_type(0, MBHEX, entities);
@@ -3005,6 +3107,7 @@
entities.clear();
MB->get_entities_by_type(0, MBVERTEX, entities);
+
// make sure the higher order nodes really were deleted
if(entities.size() != original_num_nodes)
return MB_FAILURE;
@@ -3121,17 +3224,38 @@
-
+ MBEntityHandle file_set;
file_name = TestDir + "/mbtest1.g";
- error = MB->load_mesh(file_name.c_str(), NULL, 0);
+ error = MB->load_file(file_name.c_str(), file_set);
if (error != MB_SUCCESS)
return error;
+ error = MB->delete_entities( &file_set, 1 );
+ if (MB_SUCCESS != error)
+ return error;
// delete all MBTRI's
+ MBRange tri_sets;
+ MBTag matset_tag;
+ if (MB_SUCCESS == MB->tag_get_handle( MATERIAL_SET_TAG_NAME, matset_tag )) {
+ error = MB->get_entities_by_type_and_tag( 0, MBENTITYSET, &matset_tag, 0, 1, tri_sets, MBInterface::UNION );
+ if (MB_SUCCESS != error)
+ return error;
+//MBRange users2;
+//error = dynamic_cast<MBCore*>(MB)->find_all_referencing_entities( tri_sets.front(), users2 );
+//assert(MB_SUCCESS == error);
+//users2.print();
+ error = MB->delete_entities( tri_sets );
+ if (MB_SUCCESS != error)
+ return error;
+ }
entities.clear();
error = MB->get_entities_by_type(0, MBTRI, entities);
if (MB_SUCCESS != error)
return error;
+//MBRange users;
+//error = dynamic_cast<MBCore*>(MB)->find_all_referencing_entities( entities.front(), users );
+//assert(MB_SUCCESS == error);
+//users.print();
error = MB->delete_entities(entities);
if (MB_SUCCESS != error)
return error;
Modified: MOAB/trunk/MeshSetSequence.cpp
===================================================================
--- MOAB/trunk/MeshSetSequence.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MeshSetSequence.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -49,7 +49,13 @@
// allocate storage
mSets = new unsigned char[SET_SIZE * num_entities];
+#ifdef MOAB_WITH_REFCOUNT
+ mRefCount.clear();
+ mRefCount.resize( num_entities, flags ? 1 : 0 );
+#else
mFreeEntities.clear();
+#endif
+
if (flags) {
mNumEntities = num_entities;
mFirstFreeIndex = -1;
@@ -60,7 +66,9 @@
man->notify_not_full( this );
mNumEntities = 0;
mFirstFreeIndex = 0;
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities.resize( mNumAllocated, true );
+#endif
for (MBEntityID i = 0; i < num_entities; ++i)
next_free(i) = i + 1;
next_free(num_entities-1) = -1;
@@ -89,7 +97,11 @@
return 0;
const MBEntityID index = mFirstFreeIndex;
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities[index] = false;
+#else
+ mRefCount[index] = 1;
+#endif
mFirstFreeIndex = next_free(index);
if (mLastDeletedIndex == index)
mLastDeletedIndex = -1;
@@ -98,8 +110,10 @@
mNumEntities++;
if (mNumEntities == mNumAllocated) {
mSequenceManager->notify_full(this);
+#ifndef MOAB_WITH_REFCOUNT
std::vector<bool> empty;
mFreeEntities.swap( empty);
+#endif
}
return get_start_handle() + index;
@@ -110,6 +124,12 @@
if (!is_valid_entity(handle))
return;
const MBEntityID index = handle - get_start_handle();
+
+#ifdef MOAB_WITH_REFCOUNT
+ if (get_reference_count(handle) != 1)
+ return;
+ decrement_reference_count(handle);
+#endif
// free any memory allocated by the MBMeshSet
deallocate_set( index );
@@ -117,12 +137,17 @@
// decerement count of valid entities
if(mNumEntities == mNumAllocated) {
mSequenceManager->notify_not_full(this);
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities.resize( mNumAllocated, false );
+#endif
}
--mNumEntities;
// mark this entity as invalid
+
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities[index] = true;
+#endif
// Add this entity to the free list.
// Free list is maintained in sorted order.
@@ -172,7 +197,12 @@
unsigned long& allocated ) const
{
used = 0;
- allocated = sizeof(*this) + mFreeEntities.capacity()/8;
+ allocated = sizeof(*this);
+#ifdef MOAB_WITH_REFCOUNT
+ allocated += mRefCount.capacity() * sizeof(unsigned);
+#else
+ allocated += mFreeEntities.capacity()/8;
+#endif
allocated += mNumAllocated * SET_SIZE;
for (MBEntityHandle h = get_start_handle(); h <= get_end_handle(); ++h) {
if (is_valid_entity(h)) {
@@ -501,3 +531,16 @@
number = children.size();
return result;
}
+
+#ifdef MOAB_WITH_REFCOUNT
+void MeshSetSequence::decrement_all_referenced_entities( MBEntityHandle handle, AEntityFactory* f)
+{
+ if (is_valid_entity(handle))
+ get_set( handle )->decrement_all_referenced_entities( f );
+}
+void MeshSetSequence::increment_all_referenced_entities( MBEntityHandle handle, AEntityFactory* f)
+{
+ if (is_valid_entity(handle))
+ get_set( handle )->increment_all_referenced_entities( f );
+}
+#endif
Modified: MOAB/trunk/MeshSetSequence.hpp
===================================================================
--- MOAB/trunk/MeshSetSequence.hpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/MeshSetSequence.hpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -64,6 +64,10 @@
MBErrorCode num_parents ( MBEntityHandle of, int& number, int num_hops ) const;
MBErrorCode num_children( MBEntityHandle of, int& number, int num_hops ) const;
+#ifdef MOAB_WITH_REFCOUNT
+ virtual void decrement_all_referenced_entities( MBEntityHandle , AEntityFactory* );
+ virtual void increment_all_referenced_entities( MBEntityHandle , AEntityFactory* );
+#endif
private:
void initialize( EntitySequenceManager* seq_man,
Modified: MOAB/trunk/PolyEntitySequence.cpp
===================================================================
--- MOAB/trunk/PolyEntitySequence.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/PolyEntitySequence.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -140,11 +140,17 @@
mNumEntities++;
if (mNumEntities == mNumAllocated) {
+#ifndef MOAB_WITH_REFCOUNT
std::vector<bool> empty;
mFreeEntities.swap( empty );
+#endif
mSequenceManager->notify_full(this);
}
+#ifndef MOAB_WITH_REFCOUNT
mFreeEntities[handle - get_start_handle()] = false;
+#else
+ mRefCount[handle - get_start_handle()] = 1;
+#endif
// put the connectivity on the end of that array
polyConn.insert(polyConn.end(), conn, conn+num_conn);
@@ -182,6 +188,12 @@
// add this handle to the dead list, and zero out its connectivity
MBEntityID index = entity - mStartEntityHandle;
if (!is_valid_entity(entity)) return;
+
+#ifdef MOAB_WITH_REFCOUNT
+ if (get_reference_count(entity) != 1) // only referenced by this sequence
+ return;
+ decrement_reference_count(entity);
+#endif
int start_index;
if (0 == index) start_index = 0;
@@ -191,9 +203,11 @@
// now add it to the dead list
mDeadEntities.push_back(entity);
+#ifndef MOAB_WITH_REFCOUNT
if (mFreeEntities.empty())
mFreeEntities.resize( mNumAllocated, false );
mFreeEntities[index] = true;
+#endif
// decrement number of entities
mNumEntities--;
@@ -209,11 +223,17 @@
unsigned long& allocated) const
{
allocated = sizeof(*this)
- + mFreeEntities.capacity() / 8
+ polyConn.capacity() * sizeof(MBEntityHandle)
+ mLastIndex.capacity() * sizeof(int)
+ mDeadEntities.capacity() * sizeof(MBEntityHandle)
;
+
+#ifdef MOAB_WITH_REFCOUNT
+ allocated += mRefCount.capacity() * sizeof(unsigned);
+#else
+ allocated += mFreeEntities.capacity() / 8;
+#endif
+
used = 0;
for (MBEntityHandle h = get_start_handle(); h <= get_end_handle(); ++h)
if (is_valid_entity(h))
Added: MOAB/trunk/README.RefCount
===================================================================
--- MOAB/trunk/README.RefCount (rev 0)
+++ MOAB/trunk/README.RefCount 2007-09-25 15:30:46 UTC (rev 1283)
@@ -0,0 +1,19 @@
+This branch replaces the vector<bool> of valid/invalid flags in entity
+sequences with a vector<unsigned> of reference counts. A value of zero
+for an entity signifies a hole in the sequence. A valid entity has a
+reference count of at least 1, signifying that it is referenced by it's
+owning EntitySequence.
+
+This branch contains code to update reference counts for a) entities used in
+connectivity lists, b) entities contained in sets, c) sets referenced by
+parent/child links, d) downward adjacencies, and e) entities referenced in
+handle-type tag data. Additionally, this branch contains enhancements to
+several existing algorithms that benefit from the reference count, including
+entity deletion, higher-order conversion, merging, etc.
+
+MBTest fails due to one or more bugs while deleting entity sets. The high-level
+deletion code decrmenents reference counts for contained and parent/child
+entities. However, as part of cleaning up adjacencies, updating bi-directional
+parent/child links, etc. the low-level deletion code clears the set contents,
+etc. This results in the reference count to be decremented a *second* time.
+
Modified: MOAB/trunk/ReadGmsh.cpp
===================================================================
--- MOAB/trunk/ReadGmsh.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/ReadGmsh.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -399,6 +399,8 @@
{
memcpy( conn_array, &connectivity[0], connectivity.size() * sizeof(MBEntityHandle) );
}
+
+ readMeshIface->increment_reference_count( conn_array, num_elem * node_per_elem );
// Store element IDs
result = mdbImpl->tag_set_data( globalId, elements, &elem_ids[0] );
Modified: MOAB/trunk/ReadHDF5.cpp
===================================================================
--- MOAB/trunk/ReadHDF5.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/ReadHDF5.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -429,7 +429,9 @@
return MB_FAILURE;
}
- rval = convert_id_to_handle( nodeSet, array, (size_t)(nodes_per_elem*count) );
+ rval = convert_id_to_handle( nodeSet, array, (size_t)nodes_per_elem*count );
+ if (MB_SUCCESS == rval)
+ readUtil->increment_reference_count( array, (size_t)nodes_per_elem*count );
return rval;
}
@@ -521,7 +523,10 @@
return MB_FAILURE;
}
- return convert_id_to_handle( conn_array, (size_t)data_len );
+ rval = convert_id_to_handle( conn_array, (size_t)data_len );
+ if (MB_SUCCESS == rval)
+ readUtil->increment_reference_count( conn_array, (size_t)data_len );
+ return rval;
}
template <typename T>
Modified: MOAB/trunk/ReadNCDF.cpp
===================================================================
--- MOAB/trunk/ReadNCDF.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/ReadNCDF.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -905,6 +905,7 @@
nodesInLoadedBlocks[tmp_ptr[i]] = 1;
conn[i] = static_cast<MBEntityHandle>(tmp_ptr[i]) + vertexOffset;
}
+ readMeshIface->increment_reference_count( conn, number_nodes );
readMeshIface->update_adjacencies((*this_it).startMBId, (*this_it).numElements,
ExoIIUtil::VerticesPerElement[(*this_it).elemType], conn);
Modified: MOAB/trunk/ReadSTL.cpp
===================================================================
--- MOAB/trunk/ReadSTL.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/ReadSTL.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -218,6 +218,8 @@
*connectivity = vertex_map[i->points[2]]; ++connectivity;
}
+ readMeshIface->increment_reference_count( connectivity, 3*triangles.size() );
+
return MB_SUCCESS;
}
Modified: MOAB/trunk/ReadVtk.cpp
===================================================================
--- MOAB/trunk/ReadVtk.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/ReadVtk.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -573,6 +573,8 @@
}
}
+ readMeshIface->increment_reference_count( conn_array, size[1] - size[0] );
+
return MB_SUCCESS;
}
@@ -657,11 +659,11 @@
MBEntityHandle* conn_array;
int* index_array = 0;
+ long conn_len = 0;
if (type == MBPOLYGON)
{
// Calculate total length of connectivity list
std::vector<long>::iterator conn_iter2 = conn_iter;
- long conn_len = 0;
for (i = 0; i < num_elem; ++i)
{
conn_len += *conn_iter2;
@@ -674,6 +676,7 @@
}
else
{
+ conn_len = num_elem * num_vtx;
result = allocate_elements( num_elem, num_vtx, type, start_handle,
conn_array, elem_list );
}
@@ -732,8 +735,10 @@
conn_array += num_vtx;
}
- }
+ readMeshIface->increment_reference_count( conn_array, conn_len );
+ }
+
return MB_SUCCESS;
}
@@ -793,6 +798,8 @@
*conn_array = index + corners[j] + first_vtx;
}
+
+ readMeshIface->increment_reference_count( conn_array, vert_per_elem * num_elems );
return MB_SUCCESS;
}
Modified: MOAB/trunk/TagServer.cpp
===================================================================
--- MOAB/trunk/TagServer.cpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/TagServer.cpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -591,6 +591,16 @@
return MB_SUCCESS;
}
+MBErrorCode TagServer::get_tags(MBDataType type, std::vector<MBTag> &all_tags)
+{
+ for (int i = 0; i < MB_TAG_LAST+1; ++i)
+ for (MBTagId j = 0; j < mTagTable[i].size(); ++j)
+ if (mTagTable[i][j].is_valid() && mTagTable[i][j].get_data_type() == type)
+ all_tags.push_back( TAG_HANDLE_FROM_ID( j + 1, (MBTagType)i ) );
+
+ return MB_SUCCESS;
+}
+
MBErrorCode TagServer::get_tags(const MBEntityHandle entity, std::vector<MBTag> &all_tags)
{
MBErrorCode result = MB_SUCCESS;
Modified: MOAB/trunk/TagServer.hpp
===================================================================
--- MOAB/trunk/TagServer.hpp 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/TagServer.hpp 2007-09-25 15:30:46 UTC (rev 1283)
@@ -255,6 +255,9 @@
//! get all the tags which have been defined
MBErrorCode get_tags(std::vector<MBTag> &all_tags);
+ //! get all tags that store a specified data type
+ MBErrorCode get_tags( MBDataType type, std::vector<MBTag>& tags );
+
//! get the default value for a given tag
MBErrorCode get_default_data(const MBTag tag_handle, void *data);
Modified: MOAB/trunk/configure.in
===================================================================
--- MOAB/trunk/configure.in 2007-09-25 15:19:35 UTC (rev 1282)
+++ MOAB/trunk/configure.in 2007-09-25 15:30:46 UTC (rev 1283)
@@ -47,7 +47,16 @@
fi
AC_DEFINE_UNQUOTED(MB_VERSION_STRING,"${VERSION_STRING}",[MOAB Version String])
+################################################################################
+# Debugging Features
+################################################################################
+AC_MSG_CHECKING([if reference counting is enabled])
+AC_ARG_ENABLE([refcounts],
+ [AC_HELP_STRING([enable-refcounts],[Enable reference counting])],
+ [DEFINES="$DEFINES -DMOAB_WITH_REFCOUNT"; AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])])
+
################################################################################
# Extract libtool config
################################################################################
More information about the moab-dev
mailing list