Remove INTRUSIVE_LIST from CN_ITEM
Intrusive lists made the connectivity search not thread-safe. Using iterators for item deletion provides the same order performance while keeping the container thread-localized
This commit is contained in:
parent
55784afbfe
commit
a5a56c46c3
|
@ -310,13 +310,14 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST
|
||||||
bool withinAnyNet = ( aMode != CSM_PROPAGATE );
|
bool withinAnyNet = ( aMode != CSM_PROPAGATE );
|
||||||
|
|
||||||
std::deque<CN_ITEM*> Q;
|
std::deque<CN_ITEM*> Q;
|
||||||
CN_ITEM* head = nullptr;
|
std::set<CN_ITEM*> item_set;
|
||||||
|
|
||||||
CLUSTERS clusters;
|
CLUSTERS clusters;
|
||||||
|
|
||||||
if( m_itemList.IsDirty() )
|
if( m_itemList.IsDirty() )
|
||||||
searchConnections();
|
searchConnections();
|
||||||
|
|
||||||
auto addToSearchList = [&head, withinAnyNet, aSingleNet, aTypes] ( CN_ITEM *aItem )
|
auto addToSearchList = [&item_set, withinAnyNet, aSingleNet, aTypes] ( CN_ITEM *aItem )
|
||||||
{
|
{
|
||||||
if( withinAnyNet && aItem->Net() <= 0 )
|
if( withinAnyNet && aItem->Net() <= 0 )
|
||||||
return;
|
return;
|
||||||
|
@ -341,27 +342,29 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST
|
||||||
if( !found )
|
if( !found )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
aItem->ListClear();
|
|
||||||
aItem->SetVisited( false );
|
aItem->SetVisited( false );
|
||||||
|
|
||||||
if( !head )
|
item_set.insert( aItem );
|
||||||
head = aItem;
|
|
||||||
else
|
|
||||||
head->ListInsert( aItem );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::for_each( m_itemList.begin(), m_itemList.end(), addToSearchList );
|
std::for_each( m_itemList.begin(), m_itemList.end(), addToSearchList );
|
||||||
|
|
||||||
while( head )
|
while( !item_set.empty() )
|
||||||
{
|
{
|
||||||
CN_CLUSTER_PTR cluster ( new CN_CLUSTER() );
|
CN_CLUSTER_PTR cluster ( new CN_CLUSTER() );
|
||||||
|
CN_ITEM* root;
|
||||||
|
auto it = item_set.begin();
|
||||||
|
|
||||||
Q.clear();
|
while( it != item_set.end() && (*it)->Visited() )
|
||||||
CN_ITEM* root = head;
|
it = item_set.erase( item_set.begin() );
|
||||||
|
|
||||||
|
if( it == item_set.end() )
|
||||||
|
break;
|
||||||
|
|
||||||
|
root = *it;
|
||||||
root->SetVisited ( true );
|
root->SetVisited ( true );
|
||||||
|
|
||||||
head = root->ListRemove();
|
Q.clear();
|
||||||
|
|
||||||
Q.push_back( root );
|
Q.push_back( root );
|
||||||
|
|
||||||
while( Q.size() )
|
while( Q.size() )
|
||||||
|
@ -380,7 +383,6 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST
|
||||||
{
|
{
|
||||||
n->SetVisited( true );
|
n->SetVisited( true );
|
||||||
Q.push_back( n );
|
Q.push_back( n );
|
||||||
head = n->ListRemove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ typedef std::vector<CN_ANCHOR_PTR> CN_ANCHORS;
|
||||||
|
|
||||||
|
|
||||||
// basic connectivity item
|
// basic connectivity item
|
||||||
class CN_ITEM : public INTRUSIVE_LIST<CN_ITEM>
|
class CN_ITEM
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using CONNECTED_ITEMS = std::vector<CN_ITEM*>;
|
using CONNECTED_ITEMS = std::vector<CN_ITEM*>;
|
||||||
|
|
Loading…
Reference in New Issue