7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-03-30 06:46:55 +00:00

Performance improvements for teardrop regeneration.

Avoid O(n^2) behaviour when deleting many
zones from the board zones list.
This commit is contained in:
Jeff Young 2025-02-12 12:13:52 +00:00
parent 5edae8250d
commit 281aa74f30
3 changed files with 29 additions and 23 deletions

View File

@ -1187,6 +1187,23 @@ void BOARD::FinalizeBulkRemove( std::vector<BOARD_ITEM*>& aRemovedItems )
}
void BOARD::BulkRemoveStaleTeardrops( BOARD_COMMIT& aCommit )
{
for( int ii = (int) m_zones.size() - 1; ii > 0; --ii )
{
ZONE* zone = m_zones[ii];
if( zone->IsTeardropArea() && zone->HasFlag( STRUCT_DELETED ) )
{
m_itemByIdCache.erase( zone->m_Uuid );
m_zones.erase( m_zones.begin() + ii );
m_connectivity->Remove( zone );
aCommit.Removed( zone );
}
}
}
void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
{
// find these calls and fix them! Don't send me no stinking' nullptr.

View File

@ -424,6 +424,12 @@ public:
PCB_GENERATOR_T, PCB_FOOTPRINT_T,
PCB_TRACE_T, PCB_SHAPE_T } );
/**
* Remove all teardrop zones with the STRUCT_DELETED flag set. This avoids O(n^2) traversal
* over the zone list.
*/
void BulkRemoveStaleTeardrops( BOARD_COMMIT& aCommit );
/**
* Must be used if Add() is used using a BULK_x ADD_MODE to generate a change event for
* listeners.

View File

@ -101,7 +101,6 @@ void TEARDROP_MANAGER::RemoveTeardrops( BOARD_COMMIT& aCommit,
const std::set<PCB_TRACK*>* dirtyTracks )
{
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
std::vector<ZONE*> stale_teardrops;
auto isStale =
[&]( ZONE* zone )
@ -135,14 +134,10 @@ void TEARDROP_MANAGER::RemoveTeardrops( BOARD_COMMIT& aCommit,
for( ZONE* zone : m_board->Zones() )
{
if( zone->IsTeardropArea() && isStale( zone ) )
stale_teardrops.push_back( zone );
zone->SetFlags( STRUCT_DELETED );
}
for( ZONE* td : stale_teardrops )
{
m_board->Remove( td, REMOVE_MODE::BULK );
aCommit.Removed( td );
}
m_board->BulkRemoveStaleTeardrops( aCommit );
}
@ -162,19 +157,13 @@ void TEARDROP_MANAGER::UpdateTeardrops( BOARD_COMMIT& aCommit,
// Old teardrops must be removed, to ensure a clean teardrop rebuild
if( aForceFullUpdate )
{
std::vector<ZONE*> teardrops;
for( ZONE* zone : m_board->Zones() )
{
if( zone->IsTeardropArea() )
teardrops.push_back( zone );
zone->SetFlags( STRUCT_DELETED );
}
for( ZONE* td : teardrops )
{
m_board->Remove( td, REMOVE_MODE::BULK );
aCommit.Removed( td );
}
m_board->BulkRemoveStaleTeardrops( aCommit );
}
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
@ -283,19 +272,13 @@ void TEARDROP_MANAGER::UpdateTeardrops( BOARD_COMMIT& aCommit,
void TEARDROP_MANAGER::DeleteTrackToTrackTeardrops( BOARD_COMMIT& aCommit )
{
std::vector<ZONE*> stale_teardrops;
for( ZONE* zone : m_board->Zones() )
{
if( zone->IsTeardropArea() && zone->GetTeardropAreaType() == TEARDROP_TYPE::TD_TRACKEND )
stale_teardrops.push_back( zone );
zone->SetFlags( STRUCT_DELETED );
}
for( ZONE* td : stale_teardrops )
{
m_board->Remove( td, REMOVE_MODE::BULK );
aCommit.Removed( td );
}
m_board->BulkRemoveStaleTeardrops( aCommit );
}