Performance for large hierarchies: ERC

Share constructs between ERC tests.

Large SCH_SHEET_LISTs, in particular, can be very
expensive to construct.

(cherry picked from commit 68fbe98b1d)
This commit is contained in:
Jeff Young 2024-06-06 11:20:04 +01:00
parent 7f3ca3b889
commit b19a47fa2a
2 changed files with 64 additions and 80 deletions

View File

@ -131,12 +131,9 @@ const std::set<ELECTRICAL_PINTYPE> DrivenPinTypes =
int ERC_TESTER::TestDuplicateSheetNames( bool aCreateMarker )
{
SCH_SCREEN* screen;
int err_count = 0;
int err_count = 0;
SCH_SCREENS screenList( m_schematic->Root() );
for( screen = screenList.GetFirst(); screen != nullptr; screen = screenList.GetNext() )
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
{
std::vector<SCH_SHEET*> list;
@ -197,7 +194,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
wsItems.BuildDrawItemsList( aDrawingSheet->GetPageInfo(), aDrawingSheet->GetTitleBlock() );
}
for( SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
for( const SCH_SHEET_PATH& sheet : m_sheetList )
{
SCH_SCREEN* screen = sheet.LastScreen();
@ -300,13 +297,11 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
int ERC_TESTER::TestConflictingBusAliases()
{
wxString msg;
int err_count = 0;
wxString msg;
int err_count = 0;
std::vector<std::shared_ptr<BUS_ALIAS>> aliases;
SCH_SCREENS screens( m_schematic->Root() );
std::vector< std::shared_ptr<BUS_ALIAS> > aliases;
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
{
const auto& screen_aliases = screen->GetBusAliases();
@ -347,13 +342,9 @@ int ERC_TESTER::TestConflictingBusAliases()
int ERC_TESTER::TestMultiunitFootprints()
{
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
int errors = 0;
SCH_MULTI_UNIT_REFERENCE_MAP refMap;
sheets.GetMultiUnitSymbols( refMap, true );
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : m_refMap )
{
SCH_REFERENCE_LIST& refList = symbol.second;
@ -412,14 +403,9 @@ int ERC_TESTER::TestMultiunitFootprints()
int ERC_TESTER::TestMissingUnits()
{
ERC_SETTINGS& settings = m_schematic->ErcSettings();
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
int errors = 0;
SCH_MULTI_UNIT_REFERENCE_MAP refMap;
sheets.GetMultiUnitSymbols( refMap, true );
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : m_refMap )
{
SCH_REFERENCE_LIST& refList = symbol.second;
@ -437,38 +423,38 @@ int ERC_TESTER::TestMissingUnits()
std::set<int> instance_units;
std::set<int> missing_units;
auto report_missing = [&]( std::set<int>& aMissingUnits, wxString aErrorMsg,
int aErrorCode )
{
wxString msg;
wxString missing_pin_units = wxS( "[ " );
int ii = 0;
for( int missing_unit : aMissingUnits )
{
if( ii++ == 3 )
auto report_missing =
[&]( std::set<int>& aMissingUnits, wxString aErrorMsg, int aErrorCode )
{
missing_pin_units += wxS( "....." );
break;
}
wxString msg;
wxString missing_pin_units = wxS( "[ " );
int ii = 0;
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
}
for( int missing_unit : aMissingUnits )
{
if( ii++ == 3 )
{
missing_pin_units += wxS( "....." );
break;
}
missing_pin_units.Truncate( missing_pin_units.length() - 2 );
missing_pin_units += wxS( " ]" );
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
}
msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
missing_pin_units.Truncate( missing_pin_units.length() - 2 );
missing_pin_units += wxS( " ]" );
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aErrorCode );
ercItem->SetErrorMessage( msg );
ercItem->SetItems( unit );
msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
SCH_MARKER* marker = new SCH_MARKER( ercItem, unit->GetPosition() );
base_ref.GetSheetPath().LastScreen()->Append( marker );
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aErrorCode );
ercItem->SetErrorMessage( msg );
ercItem->SetItems( unit );
++errors;
};
SCH_MARKER* marker = new SCH_MARKER( ercItem, unit->GetPosition() );
base_ref.GetSheetPath().LastScreen()->Append( marker );
++errors;
};
for( int ii = 1; ii <= libSymbol->GetUnitCount(); ++ii )
lib_units.insert( lib_units.end(), ii );
@ -480,7 +466,7 @@ int ERC_TESTER::TestMissingUnits()
instance_units.begin(), instance_units.end(),
std::inserter( missing_units, missing_units.begin() ) );
if( !missing_units.empty() && settings.IsTestEnabled( ERCE_MISSING_UNIT ) )
if( !missing_units.empty() && m_settings.IsTestEnabled( ERCE_MISSING_UNIT ) )
{
report_missing( missing_units, _( "Symbol %s has unplaced units %s" ),
ERCE_MISSING_UNIT );
@ -528,21 +514,21 @@ int ERC_TESTER::TestMissingUnits()
}
}
if( !missing_power.empty() && settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN ) )
if( !missing_power.empty() && m_settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN ) )
{
report_missing( missing_power,
_( "Symbol %s has input power pins in units %s that are not placed." ),
ERCE_MISSING_POWER_INPUT_PIN );
}
if( !missing_input.empty() && settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN ) )
if( !missing_input.empty() && m_settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN ) )
{
report_missing( missing_input,
_( "Symbol %s has input pins in units %s that are not placed." ),
ERCE_MISSING_INPUT_PIN );
}
if( !missing_bidi.empty() && settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
if( !missing_bidi.empty() && m_settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
{
report_missing( missing_bidi,
_( "Symbol %s has bidirectional pins in units %s that are not "
@ -576,7 +562,7 @@ int ERC_TESTER::TestMissingNetclasses()
sheet.LastScreen()->Append( marker );
};
for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
for( const SCH_SHEET_PATH& sheet : m_sheetList )
{
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
{
@ -612,7 +598,7 @@ int ERC_TESTER::TestNoConnectPins()
{
int err_count = 0;
for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
for( const SCH_SHEET_PATH& sheet : m_sheetList )
{
std::map<VECTOR2I, std::vector<SCH_ITEM*>> pinMap;
@ -679,12 +665,9 @@ int ERC_TESTER::TestNoConnectPins()
int ERC_TESTER::TestPinToPin()
{
ERC_SETTINGS& settings = m_schematic->ErcSettings();
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
int errors = 0;
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
{
std::vector<ERC_SCH_PIN_CONTEXT> pins;
std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
@ -780,9 +763,9 @@ int ERC_TESTER::TestPinToPin()
else
hasDriver |= ( DrivingPinTypes.count( testType ) != 0 );
PIN_ERROR erc = settings.GetPinMapValue( refType, testType );
PIN_ERROR erc = m_settings.GetPinMapValue( refType, testType );
if( erc != PIN_ERROR::OK && settings.IsTestEnabled( ERCE_PIN_TO_PIN_WARNING ) )
if( erc != PIN_ERROR::OK && m_settings.IsTestEnabled( ERCE_PIN_TO_PIN_WARNING ) )
{
std::shared_ptr<ERC_ITEM> ercItem =
ERC_ITEM::Create( erc == PIN_ERROR::WARNING ? ERCE_PIN_TO_PIN_WARNING :
@ -808,7 +791,7 @@ int ERC_TESTER::TestPinToPin()
{
int err_code = ispowerNet ? ERCE_POWERPIN_NOT_DRIVEN : ERCE_PIN_NOT_DRIVEN;
if( settings.IsTestEnabled( err_code ) )
if( m_settings.IsTestEnabled( err_code ) )
{
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( err_code );
@ -830,13 +813,11 @@ int ERC_TESTER::TestPinToPin()
int ERC_TESTER::TestMultUnitPinConflicts()
{
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
int errors = 0;
std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
{
const wxString& netName = net.first.Name;
@ -890,13 +871,11 @@ int ERC_TESTER::TestMultUnitPinConflicts()
int ERC_TESTER::TestSimilarLabels()
{
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
int errors = 0;
std::unordered_map<wxString, std::pair<SCH_LABEL_BASE*, SCH_SHEET_PATH>> labelMap;
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
{
for( CONNECTION_SUBGRAPH* subgraph : net.second )
{
@ -957,9 +936,7 @@ int ERC_TESTER::TestLibSymbolIssues()
wxString msg;
int err_count = 0;
SCH_SCREENS screens( m_schematic->Root() );
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
{
std::vector<SCH_MARKER*> markers;
@ -1042,11 +1019,9 @@ int ERC_TESTER::TestLibSymbolIssues()
int ERC_TESTER::TestOffGridEndpoints()
{
const int gridSize = m_schematic->Settings().m_ConnectionGridSize;
int err_count = 0;
SCH_SCREENS screens( m_schematic->Root() );
int err_count = 0;
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
{
std::vector<SCH_MARKER*> markers;
@ -1108,11 +1083,10 @@ int ERC_TESTER::TestSimModelIssues()
{
wxString msg;
WX_STRING_REPORTER reporter( &msg );
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
int err_count = 0;
SIM_LIB_MGR libMgr( &m_schematic->Prj() );
for( SCH_SHEET_PATH& sheet : sheets )
for( SCH_SHEET_PATH& sheet : m_sheetList )
{
std::vector<SCH_MARKER*> markers;

View File

@ -27,9 +27,10 @@
#define ERC_H
#include <erc_settings.h>
#include <sch_screen.h>
#include <connection_graph.h>
class SCH_SHEET_LIST;
class SCHEMATIC;
class DS_PROXY_VIEW_ITEM;
class SCH_EDIT_FRAME;
@ -47,8 +48,13 @@ class ERC_TESTER
public:
ERC_TESTER( SCHEMATIC* aSchematic ) :
m_schematic( aSchematic )
m_schematic( aSchematic ),
m_settings( aSchematic->ErcSettings() ),
m_sheetList( aSchematic->GetSheets() ),
m_screens( aSchematic->Root() ),
m_nets( aSchematic->ConnectionGraph()->GetNetMap() )
{
m_sheetList.GetMultiUnitSymbols( m_refMap, true );
}
/**
@ -139,8 +145,12 @@ public:
KIFACE* aCvPcb, PROJECT* aProject, PROGRESS_REPORTER* aProgressReporter );
private:
SCHEMATIC* m_schematic;
SCHEMATIC* m_schematic;
ERC_SETTINGS& m_settings;
SCH_SHEET_LIST m_sheetList;
SCH_SCREENS m_screens;
SCH_MULTI_UNIT_REFERENCE_MAP m_refMap;
const NET_MAP& m_nets;
};