7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-18 21:29:17 +00:00

Performance improvements.

1) Move a bunch of std::map's to std::unordered_map to get constant-time
look-ups
2) Lengthen progress-reporting intervals to spend more time doing work
and less time talking about it
3) Reverse order of SHAPE_LINE_CHAINs in thermal intersection checks to
make (much) better use of bbox caches
4) Don't re-generate bboxes we already have
5) Fix some autos that weren't by reference (and were therefore copying
large datasets)
6) Rename delta progressDelta so it's easier to search for in future
7) Get rid of a few more autos (because I don't like them)
8) Pass large items to lambdas by reference

Fixes https://gitlab.com/kicad/code/kicad/issues/12130
This commit is contained in:
Jeff Young 2022-08-03 10:10:23 +01:00
parent 26cbdcf3fa
commit 96f01d33c8
44 changed files with 352 additions and 236 deletions

View File

@ -87,7 +87,7 @@ void DS_DATA_ITEM::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::VIEW* aV
pensize = aCollector ? aCollector->GetDefaultPenSize() : 0;
std::map<size_t, EDA_ITEM_FLAGS> itemFlags;
DS_DRAW_ITEM_BASE* item = nullptr;
DS_DRAW_ITEM_BASE* item = nullptr;
for( size_t i = 0; i < m_drawItems.size(); ++i )
{

View File

@ -989,7 +989,7 @@ void CONNECTION_GRAPH::generateInvisiblePinSubGraphs()
subgraph->AddItem( pin );
subgraph->ResolveDrivers();
auto key = std::make_pair( subgraph->GetNetName(), code );
NET_NAME_CODE_CACHE_KEY key = { subgraph->GetNetName(), code };
m_net_code_to_subgraphs_map[ key ].push_back( subgraph );
m_subgraphs.push_back( subgraph );
m_driver_subgraphs.push_back( subgraph );
@ -1609,8 +1609,8 @@ void CONNECTION_GRAPH::buildConnectionGraph()
for( CONNECTION_SUBGRAPH* subgraph : m_driver_subgraphs )
{
auto key = std::make_pair( subgraph->GetNetName(),
subgraph->m_driver_connection->NetCode() );
NET_NAME_CODE_CACHE_KEY key = { subgraph->GetNetName(),
subgraph->m_driver_connection->NetCode() };
m_net_code_to_subgraphs_map[ key ].push_back( subgraph );
m_net_name_to_subgraphs_map[subgraph->m_driver_connection->Name()].push_back( subgraph );

View File

@ -236,11 +236,33 @@ public:
SCH_ITEM* m_second_driver;
};
/// Associates a net code with the final name of a net
typedef std::pair<wxString, int> NET_NAME_CODE;
struct NET_NAME_CODE_CACHE_KEY
{
wxString Name;
int Netcode;
bool operator==(const NET_NAME_CODE_CACHE_KEY& other) const
{
return Name == other.Name && Netcode == other.Netcode;
}
};
namespace std
{
template <>
struct hash<NET_NAME_CODE_CACHE_KEY>
{
std::size_t operator()( const NET_NAME_CODE_CACHE_KEY& k ) const
{
const std::size_t prime = 19937;
return hash<wxString>()( k.Name ) ^ ( hash<int>()( k.Netcode ) * prime );
}
};
}
/// Associates a NET_CODE_NAME with all the subgraphs in that net
typedef std::map<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> NET_MAP;
typedef std::unordered_map<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> NET_MAP;
/**
* Calculates the connectivity of a schematic and generates netlists
@ -552,20 +574,20 @@ private:
std::vector<std::pair<SCH_SHEET_PATH, SCH_PIN*>> m_invisible_power_pins;
std::unordered_map< wxString, std::shared_ptr<BUS_ALIAS> > m_bus_alias_cache;
std::unordered_map<wxString, std::shared_ptr<BUS_ALIAS>> m_bus_alias_cache;
std::map<wxString, int> m_net_name_to_code_map;
std::unordered_map<wxString, int> m_net_name_to_code_map;
std::map<wxString, int> m_bus_name_to_code_map;
std::unordered_map<wxString, int> m_bus_name_to_code_map;
std::map<wxString, std::vector<const CONNECTION_SUBGRAPH*>> m_global_label_cache;
std::unordered_map<wxString, std::vector<const CONNECTION_SUBGRAPH*>> m_global_label_cache;
std::map< std::pair<SCH_SHEET_PATH, wxString>,
std::vector<const CONNECTION_SUBGRAPH*> > m_local_label_cache;
std::unordered_map<wxString, std::vector<CONNECTION_SUBGRAPH*>> m_net_name_to_subgraphs_map;
std::map<SCH_ITEM*, CONNECTION_SUBGRAPH*> m_item_to_subgraph_map;
std::unordered_map<SCH_ITEM*, CONNECTION_SUBGRAPH*> m_item_to_subgraph_map;
NET_MAP m_net_code_to_subgraphs_map;

View File

@ -405,7 +405,7 @@ int ERC_TESTER::TestNoConnectPins()
for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
{
std::map<VECTOR2I, std::vector<SCH_PIN*>> pinMap;
std::unordered_map<VECTOR2I, std::vector<SCH_PIN*>> pinMap;
for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
{
@ -448,7 +448,7 @@ int ERC_TESTER::TestPinToPin()
int errors = 0;
for( const std::pair<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
{
std::vector<SCH_PIN*> pins;
std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
@ -596,9 +596,9 @@ int ERC_TESTER::TestMultUnitPinConflicts()
std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
for( const std::pair<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
{
const wxString& netName = net.first.first;
const wxString& netName = net.first.Name;
for( CONNECTION_SUBGRAPH* subgraph : net.second )
{
@ -654,7 +654,7 @@ int ERC_TESTER::TestSimilarLabels()
std::unordered_map<wxString, SCH_LABEL_BASE*> labelMap;
for( const std::pair<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
{
for( CONNECTION_SUBGRAPH* subgraph : net.second )
{

View File

@ -118,9 +118,9 @@ bool NETLIST_EXPORTER_CADSTAR::writeListOfNets( FILE* f )
for( const auto& it : m_schematic->ConnectionGraph()->GetNetMap() )
{
auto subgraphs = it.second;
const std::vector<CONNECTION_SUBGRAPH*>& subgraphs = it.second;
netName.Printf( wxT( "\"%s\"" ), it.first.first );
netName.Printf( wxT( "\"%s\"" ), it.first.Name );
std::vector<std::pair<SCH_PIN*, SCH_SHEET_PATH>> sorted_items;

View File

@ -670,9 +670,9 @@ XNODE* NETLIST_EXPORTER_XML::makeListOfNets( unsigned aCtl )
for( const auto& it : m_schematic->ConnectionGraph()->GetNetMap() )
{
wxString net_name = it.first.first;
auto subgraphs = it.second;
NET_RECORD* net_record;
wxString net_name = it.first.Name;
const std::vector<CONNECTION_SUBGRAPH*>& subgraphs = it.second;
NET_RECORD* net_record = nullptr;
if( subgraphs.empty() )
continue;

View File

@ -484,7 +484,7 @@ protected:
// to store a initial pos of the item or mouse cursor
/// Store pointers to other items that are connected to this one, per sheet.
std::map<SCH_SHEET_PATH, SCH_ITEM_SET, SHEET_PATH_CMP> m_connected_items;
std::unordered_map<SCH_SHEET_PATH, SCH_ITEM_SET, SHEET_PATH_HASH, SHEET_PATH_CMP> m_connected_items;
/// Store connectivity information, per sheet.
std::unordered_map<SCH_SHEET_PATH, SCH_CONNECTION*> m_connection_map;

View File

@ -400,6 +400,14 @@ namespace std
};
}
struct SHEET_PATH_HASH
{
const size_t operator()( const SCH_SHEET_PATH& path ) const
{
return path.GetCurrentHash();
}
};
struct SHEET_PATH_CMP
{
bool operator()( const SCH_SHEET_PATH& lhs, const SCH_SHEET_PATH& rhs ) const

View File

@ -241,7 +241,6 @@ std::vector<wxString> SCHEMATIC::GetNetClassAssignmentCandidates()
{
std::vector<wxString> names;
// Key is a NET_NAME_CODE aka std::pair<name, code>
for( const NET_MAP::value_type& pair: m_connectionGraph->GetNetMap() )
{
CONNECTION_SUBGRAPH* subgraph = pair.second[0];
@ -249,7 +248,7 @@ std::vector<wxString> SCHEMATIC::GetNetClassAssignmentCandidates()
if( !subgraph->m_driver_connection->IsBus()
&& subgraph->GetDriverPriority() >= CONNECTION_SUBGRAPH::PRIORITY::PIN )
{
names.emplace_back( pair.first.first );
names.emplace_back( pair.first.Name );
}
}

View File

@ -645,7 +645,8 @@ public:
* @return the number of intersections found.
*/
int Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp,
bool aExcludeColinearAndTouching = false ) const;
bool aExcludeColinearAndTouching = false,
BOX2I* aChainBBox = nullptr ) const;
/**
* Compute the walk path length from the beginning of the line chain and the point \a aP

View File

@ -1395,9 +1395,9 @@ static inline void addIntersection( SHAPE_LINE_CHAIN::INTERSECTIONS& aIps, int a
int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp,
bool aExcludeColinearAndTouching ) const
bool aExcludeColinearAndTouching, BOX2I* aChainBBox ) const
{
BOX2I bb_other = aChain.BBox();
BOX2I bb_other = aChainBBox ? *aChainBBox : aChain.BBox();
for( int s1 = 0; s1 < SegmentCount(); s1++ )
{

View File

@ -665,7 +665,7 @@ void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector<
returns.emplace_back( tp.submit( cache_zones, zone ) );
// Finalize the triangulation threads
for( auto& retval : returns )
for( const std::future<size_t>& retval : returns )
{
std::future_status status;
@ -674,8 +674,9 @@ void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector<
if( aReporter )
aReporter->KeepRefreshing();
status = retval.wait_for( std::chrono::milliseconds( 100 ) );
} while( status != std::future_status::ready );
status = retval.wait_for( std::chrono::milliseconds( 250 ) );
}
while( status != std::future_status::ready );
}
}

View File

@ -63,6 +63,54 @@ class PROGRESS_REPORTER;
// Forward declare endpoint from class_track.h
enum ENDPOINT_T : int;
struct PTR_PTR_CACHE_KEY
{
BOARD_ITEM* A;
BOARD_ITEM* B;
bool operator==(const PTR_PTR_CACHE_KEY& other) const
{
return A == other.A && B == other.B;
}
};
struct PTR_PTR_LAYER_CACHE_KEY
{
BOARD_ITEM* A;
BOARD_ITEM* B;
PCB_LAYER_ID Layer;
bool operator==(const PTR_PTR_LAYER_CACHE_KEY& other) const
{
return A == other.A && B == other.B && Layer == other.Layer;
}
};
namespace std
{
template <>
struct hash<PTR_PTR_CACHE_KEY>
{
std::size_t operator()( const PTR_PTR_CACHE_KEY& k ) const
{
return hash<void*>()( k.A ) ^ hash<void*>()( k.B );
}
};
template <>
struct hash<PTR_PTR_LAYER_CACHE_KEY>
{
std::size_t operator()( const PTR_PTR_LAYER_CACHE_KEY& k ) const
{
const std::size_t prime = 19937;
return hash<void*>()( k.A ) ^ hash<void*>()( k.B ) ^ ( hash<int>()( k.Layer ) * prime );
}
};
}
/**
* The allowed types of layers, same as Specctra DSN spec.
*/
@ -1071,14 +1119,14 @@ public:
};
// ------------ Run-time caches -------------
std::mutex m_CachesMutex;
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, bool > m_InsideCourtyardCache;
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, bool > m_InsideFCourtyardCache;
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, bool > m_InsideBCourtyardCache;
std::map< std::tuple<BOARD_ITEM*, BOARD_ITEM*, PCB_LAYER_ID>, bool > m_InsideAreaCache;
std::map< wxString, LSET > m_LayerExpressionCache;
std::map< ZONE*, std::unique_ptr<DRC_RTREE> > m_CopperZoneRTreeCache;
std::unique_ptr<DRC_RTREE> m_CopperItemRTreeCache;
std::mutex m_CachesMutex;
std::unordered_map<PTR_PTR_CACHE_KEY, bool> m_InsideCourtyardCache;
std::unordered_map<PTR_PTR_CACHE_KEY, bool> m_InsideFCourtyardCache;
std::unordered_map<PTR_PTR_CACHE_KEY, bool> m_InsideBCourtyardCache;
std::unordered_map<PTR_PTR_LAYER_CACHE_KEY, bool> m_InsideAreaCache;
std::unordered_map< wxString, LSET > m_LayerExpressionCache;
std::unordered_map<ZONE*, std::unique_ptr<DRC_RTREE>> m_CopperZoneRTreeCache;
std::unique_ptr<DRC_RTREE> m_CopperItemRTreeCache;
// ------------ DRC caches -------------
std::vector<ZONE*> m_DRCZones;
@ -1148,4 +1196,5 @@ private:
std::vector<BOARD_LISTENER*> m_listeners;
};
#endif // CLASS_BOARD_H_

View File

@ -245,7 +245,7 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
auto conn_lambda =
[&dirtyItems]( size_t aItem, CN_LIST* aItemList,
PROGRESS_REPORTER* aReporter) -> size_t
PROGRESS_REPORTER* aReporter) -> size_t
{
if( aReporter && aReporter->IsCancelled() )
return 0;
@ -262,17 +262,18 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
for( size_t ii = 0; ii < dirtyItems.size(); ++ii )
returns[ii] = tp.submit( conn_lambda, ii, &m_itemList, m_progressReporter );
for( auto& retval : returns )
for( const std::future<size_t>& retval : returns )
{
// Here we balance returns with a 100ms timeout to allow UI updating
// Here we balance returns with a 250ms timeout to allow UI updating
std::future_status status;
do
{
if( m_progressReporter )
m_progressReporter->KeepRefreshing();
status = retval.wait_for( std::chrono::milliseconds( 100 ) );
} while( status != std::future_status::ready );
status = retval.wait_for( std::chrono::milliseconds( 250 ) );
}
while( status != std::future_status::ready );
}
if( m_progressReporter )
@ -299,7 +300,8 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST
const CN_CONNECTIVITY_ALGO::CLUSTERS
CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode, const std::initializer_list<KICAD_T>& aTypes,
CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode,
const std::initializer_list<KICAD_T>& aTypes,
int aSingleNet, CN_ITEM* rootItem )
{
bool withinAnyNet = ( aMode != CSM_PROPAGATE );
@ -313,7 +315,7 @@ CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode, const std::init
searchConnections();
auto addToSearchList =
[&item_set, withinAnyNet, aSingleNet, aTypes, rootItem ]( CN_ITEM *aItem )
[&item_set, withinAnyNet, aSingleNet, &aTypes, rootItem ]( CN_ITEM *aItem )
{
if( withinAnyNet && aItem->Net() <= 0 )
return;
@ -428,7 +430,7 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
// Setup progress metrics
//
int delta = 50; // Number of additions between 2 calls to the progress bar
int progressDelta = 50;
double size = 0.0;
size += zitems.size(); // Once for building RTrees
@ -440,12 +442,12 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
size *= 1.5; // Our caller gets the other third of the progress bar
delta = std::max( delta, KiROUND( size / 10 ) );
progressDelta = std::max( progressDelta, (int) size / 4 );
auto report =
[&]( int progress )
{
if( aReporter && ( progress % delta ) == 0 )
if( aReporter && ( progress % progressDelta ) == 0 )
{
aReporter->SetCurrentProgress( progress / size );
aReporter->KeepRefreshing( false );
@ -457,12 +459,13 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
thread_pool& tp = GetKiCadThreadPool();
std::vector<std::future<size_t>> returns( zitems.size() );
auto cache_zones = [aReporter]( CN_ZONE_LAYER* aZone ) -> size_t
auto cache_zones =
[aReporter]( CN_ZONE_LAYER* aZoneLayer ) -> size_t
{
if( aReporter && aReporter->IsCancelled() )
return 0;
aZone->BuildRTree();
aZoneLayer->BuildRTree();
if( aReporter )
aReporter->AdvanceProgress();
@ -473,7 +476,7 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
for( size_t ii = 0; ii < zitems.size(); ++ii )
returns[ii] = tp.submit( cache_zones, zitems[ii] );
for( auto& retval : returns )
for( const std::future<size_t>& retval : returns )
{
std::future_status status;
@ -482,8 +485,9 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
if( aReporter )
aReporter->KeepRefreshing();
status = retval.wait_for( std::chrono::milliseconds( 100 ) );
} while( status != std::future_status::ready );
status = retval.wait_for( std::chrono::milliseconds( 250 ) );
}
while( status != std::future_status::ready );
}
@ -575,7 +579,7 @@ void CN_CONNECTIVITY_ALGO::propagateConnections( BOARD_COMMIT* aCommit, PROPAGAT
// normal cluster: just propagate from the pads
int n_changed = 0;
for( auto item : *cluster )
for( CN_ITEM* item : *cluster )
{
if( item->CanChangeNet() )
{
@ -601,8 +605,10 @@ void CN_CONNECTIVITY_ALGO::propagateConnections( BOARD_COMMIT* aCommit, PROPAGAT
(const char*) cluster->OriginNetName().c_str() );
}
else
{
wxLogTrace( wxT( "CN" ), wxT( "Cluster %p : nothing to propagate" ),
cluster.get() );
}
}
else
{
@ -651,9 +657,11 @@ void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( ZONE* aZone, PCB_LAYER_ID
void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones,
bool aConnectivityAlreadyRebuilt )
{
int delta = 10; // Number of additions between 2 calls to the progress bar
int progressDelta = 50;
int ii = 0;
progressDelta = std::max( progressDelta, (int) aZones.size() / 4 );
if( !aConnectivityAlreadyRebuilt )
{
for( CN_ZONE_ISOLATED_ISLAND_LIST& z : aZones )
@ -662,7 +670,7 @@ void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLAT
Add( z.m_zone );
ii++;
if( m_progressReporter && ( ii % delta ) == 0 )
if( m_progressReporter && ( ii % progressDelta ) == 0 )
{
m_progressReporter->SetCurrentProgress( (double) ii / (double) aZones.size() );
m_progressReporter->KeepRefreshing( false );

View File

@ -193,7 +193,7 @@ public:
return m_dirtyNets.size();
}
void Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter = nullptr );
void Build( BOARD* aZoneLayer, PROGRESS_REPORTER* aReporter = nullptr );
void LocalBuild( const std::vector<BOARD_ITEM*>& aItems );
void Clear();

View File

@ -92,7 +92,7 @@ bool DRC_CACHE_GENERATOR::Run()
}
// This is the number of tests between 2 calls to the progress bar
size_t delta = 50;
size_t progressDelta = 200;
size_t count = 0;
size_t ii = 0;
@ -106,7 +106,7 @@ bool DRC_CACHE_GENERATOR::Run()
auto addToCopperTree =
[&]( BOARD_ITEM* item ) -> bool
{
if( !reportProgress( ii++, count, delta ) )
if( !reportProgress( ii++, count, progressDelta ) )
return false;
LSET layers = item->GetLayerSet();
@ -149,17 +149,17 @@ bool DRC_CACHE_GENERATOR::Run()
// Cache zone bounding boxes, triangulation, copper zone rtrees, and footprint courtyards
// before we start.
m_drcEngine->SetMaxProgress( allZones.size() );
for( FOOTPRINT* footprint : m_board->Footprints() )
footprint->BuildCourtyardCaches();
thread_pool& tp = GetKiCadThreadPool();
std::vector<std::future<size_t>> returns;
std::atomic<size_t> done( 1 );
returns.reserve( allZones.size() );
auto cache_zones = [this]( ZONE* aZone ) -> size_t
auto cache_zones =
[this, &done]( ZONE* aZone ) -> size_t
{
if( m_drcEngine->IsCancelled() )
return 0;
@ -179,7 +179,8 @@ bool DRC_CACHE_GENERATOR::Run()
std::unique_lock<std::mutex> cacheLock( m_board->m_CachesMutex );
m_board->m_CopperZoneRTreeCache[ aZone ] = std::move( rtree );
m_drcEngine->AdvanceProgress();
done.fetch_add( 1 );
}
return 1;
@ -188,15 +189,16 @@ bool DRC_CACHE_GENERATOR::Run()
for( ZONE* zone : allZones )
returns.emplace_back( tp.submit( cache_zones, zone ) );
for( auto& retval : returns )
for( const std::future<size_t>& retval : returns )
{
std::future_status status;
do
{
m_drcEngine->KeepRefreshing();
status = retval.wait_for( std::chrono::milliseconds( 100 ) );
} while( status != std::future_status::ready );
m_drcEngine->ReportProgress( static_cast<double>( done ) / allZones.size() );
status = retval.wait_for( std::chrono::milliseconds( 250 ) );
}
while( status != std::future_status::ready );
}
return !m_drcEngine->IsCancelled();

View File

@ -77,7 +77,7 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run()
return true; // continue with other tests
}
const int delta = 250; // This is the number of tests between 2 calls to the progress bar
const int progressDelta = 500;
if( !m_drcEngine->HasRulesForConstraintType( ANNULAR_WIDTH_CONSTRAINT ) )
{
@ -126,7 +126,7 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run()
}
}
return 100;
return 5;
}
default:
@ -286,7 +286,7 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run()
{
ii += calcEffort( item );
if( !reportProgress( ii, total, delta ) )
if( !reportProgress( ii, total, progressDelta ) )
return false; // DRC cancelled
if( !checkAnnularWidth( item ) )
@ -299,7 +299,7 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run()
{
ii += calcEffort( pad );
if( !reportProgress( ii, total, delta ) )
if( !reportProgress( ii, total, progressDelta ) )
return false; // DRC cancelled
if( !checkAnnularWidth( pad ) )

View File

@ -736,7 +736,7 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
for( const std::pair<const std::pair<int, PCB_LAYER_ID>, ITEMS_POLY>& netLayer : dataset )
total_effort += calc_effort( netLayer.second.items, netLayer.first.second );
total_effort += total_effort * distinctMinWidths.size();
total_effort += std::max( (size_t) 1, total_effort ) * distinctMinWidths.size();
returns.reserve( dataset.size() );
@ -753,8 +753,9 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
do
{
m_drcEngine->ReportProgress( static_cast<double>( done ) / total_effort );
status = retval.wait_for( std::chrono::milliseconds( 100 ) );
} while( status != std::future_status::ready );
status = retval.wait_for( std::chrono::milliseconds( 250 ) );
}
while( status != std::future_status::ready );
}
returns.clear();
@ -776,8 +777,9 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
do
{
m_drcEngine->ReportProgress( static_cast<double>( done ) / total_effort );
status = retval.wait_for( std::chrono::milliseconds( 100 ) );
} while( status != std::future_status::ready );
status = retval.wait_for( std::chrono::milliseconds( 250 ) );
}
while( status != std::future_status::ready );
}
return true;

View File

@ -87,7 +87,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
connectivity->Build( board, m_drcEngine->GetProgressReporter() );
connectivity->FindIsolatedCopperIslands( islandsList, true );
int delta = 100; // This is the number of tests between 2 calls to the progress bar
int progressDelta = 250;
int ii = 0;
int count = board->Tracks().size() + islandsList.size();
@ -106,7 +106,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
else if( track->Type() == PCB_TRACE_T && exceedT )
continue;
if( !reportProgress( ii++, count, delta ) )
if( !reportProgress( ii++, count, progressDelta ) )
return false; // DRC cancelled
// Test for dangling items
@ -127,7 +127,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
if( m_drcEngine->IsErrorLimitExceeded( DRCE_ISOLATED_COPPER ) )
break;
if( !reportProgress( ii++, count, delta ) )
if( !reportProgress( ii++, count, progressDelta ) )
return false; // DRC cancelled
for( PCB_LAYER_ID layer : zone.m_zone->GetLayerSet().Seq() )
@ -158,7 +158,6 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
std::vector<CN_EDGE> edges;
connectivity->GetUnconnectedEdges( edges );
delta = 250;
ii = 0;
count = edges.size();
@ -167,7 +166,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNCONNECTED_ITEMS ) )
break;
if( !reportProgress( ii++, count, delta ) )
if( !reportProgress( ii++, count, progressDelta ) )
return false; // DRC cancelled
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNCONNECTED_ITEMS );

View File

@ -413,16 +413,16 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZone( BOARD_ITEM* aItem,
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
{
// This is the number of tests between 2 calls to the progress bar
const int delta = 100;
const int progressDelta = 100;
int ii = 0;
reportAux( wxT( "Testing %d tracks & vias..." ), m_board->Tracks().size() );
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, int> checkedPairs;
std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
for( PCB_TRACK* track : m_board->Tracks() )
{
if( !reportProgress( ii++, m_board->Tracks().size(), delta ) )
if( !reportProgress( ii++, m_board->Tracks().size(), progressDelta ) )
break;
for( PCB_LAYER_ID layer : track->GetLayerSet().Seq() )
@ -687,17 +687,16 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
{
const int delta = 50; // This is the number of tests between 2 calls to the progress bar
size_t count = 0;
const int progressDelta = 100;
size_t count = 0;
int ii = 0;
for( FOOTPRINT* footprint : m_board->Footprints() )
count += footprint->Pads().size();
reportAux( wxT( "Testing %d pads..." ), count );
int ii = 0;
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, int> checkedPairs;
std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
for( FOOTPRINT* footprint : m_board->Footprints() )
{
@ -745,7 +744,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
}
}
if( !reportProgress( ii++, count, delta ) )
if( !reportProgress( ii++, count, progressDelta ) )
return;
}
@ -757,7 +756,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
{
const int delta = 50; // This is the number of tests between 2 calls to the progress bar
const int progressDelta = 50;
SHAPE_POLY_SET buffer;
SHAPE_POLY_SET* boardOutline = nullptr;
@ -790,7 +789,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
for( size_t ia = 0; ia < m_board->m_DRCCopperZones.size(); ia++ )
{
if( !reportProgress( layer_id * m_board->m_DRCCopperZones.size() + ia,
B_Cu * m_board->m_DRCCopperZones.size(), delta ) )
B_Cu * m_board->m_DRCCopperZones.size(), progressDelta ) )
{
return; // DRC cancelled
}

View File

@ -78,8 +78,6 @@ private:
bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
{
const int delta = 100; // This is the number of tests between 2 calls to the progress bar
// Detects missing (or malformed) footprint courtyards
if( !m_drcEngine->IsErrorLimitExceeded( DRCE_MALFORMED_COURTYARD)
|| !m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_COURTYARD) )
@ -98,11 +96,12 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
return true; // continue with other tests
}
int ii = 0;
const int progressDelta = 500;
int ii = 0;
for( FOOTPRINT* footprint : m_board->Footprints() )
{
if( !reportProgress( ii++, m_board->Footprints().size(), delta ) )
if( !reportProgress( ii++, m_board->Footprints().size(), progressDelta ) )
return false; // DRC cancelled
if( ( footprint->GetFlags() & MALFORMED_COURTYARDS ) != 0 )
@ -148,16 +147,15 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
{
const int delta = 100; // This is the number of tests between 2 calls to the progress bar
if( !reportPhase( _( "Checking footprints for overlapping courtyards..." ) ) )
return false; // DRC cancelled
int ii = 0;
const int progressDelta = 100;
int ii = 0;
for( auto itA = m_board->Footprints().begin(); itA != m_board->Footprints().end(); itA++ )
{
if( !reportProgress( ii++, m_board->Footprints().size(), delta ) )
if( !reportProgress( ii++, m_board->Footprints().size(), progressDelta ) )
return false; // DRC cancelled
if( m_drcEngine->IsErrorLimitExceeded( DRCE_OVERLAPPING_FOOTPRINTS)

View File

@ -150,9 +150,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
if( m_drcEngine->IsCancelled() )
return 0;
std::tuple<BOARD_ITEM*, BOARD_ITEM*, PCB_LAYER_ID> key( ruleArea,
copperZone,
UNDEFINED_LAYER );
PTR_PTR_LAYER_CACHE_KEY key = { ruleArea, copperZone, UNDEFINED_LAYER };
{
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
@ -179,8 +177,9 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
do
{
m_drcEngine->ReportProgress( static_cast<double>( done ) / toCache.size() );
status = retval.wait_for( std::chrono::milliseconds( 100 ) );
} while( status != std::future_status::ready );
status = retval.wait_for( std::chrono::milliseconds( 250 ) );
}
while( status != std::future_status::ready );
}
if( m_drcEngine->IsCancelled() )
@ -189,8 +188,8 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
// Now go through all the board objects calling the DRC_ENGINE to run the actual disallow
// tests. These should be reasonably quick using the caches generated above.
//
int delta = 100;
int ii = static_cast<int>( toCache.size() );
const int progressDelta = 250;
int ii = static_cast<int>( toCache.size() );
auto checkTextOnEdgeCuts =
[&]( BOARD_ITEM* item )
@ -258,7 +257,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
}
}
if( !reportProgress( ii++, totalCount, delta ) )
if( !reportProgress( ii++, totalCount, progressDelta ) )
return false;
return true;

View File

@ -246,8 +246,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
}
}
// This is the number of tests between 2 calls to the progress bar
const int delta = 100;
const int progressDelta = 200;
int count = 0;
int ii = 0;
@ -267,7 +266,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
if( !testCopper && !testSilk )
return false; // We're done
if( !reportProgress( ii++, count, delta ) )
if( !reportProgress( ii++, count, progressDelta ) )
return false; // DRC cancelled; we're done
if( isInvisibleText( item ) )

View File

@ -120,8 +120,7 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::Run()
if( !reportPhase( _( "Checking hole to hole clearances..." ) ) )
return false; // DRC cancelled
// This is the number of tests between 2 calls to the progress bar
const size_t delta = 100;
const size_t progressDelta = 200;
size_t count = 0;
size_t ii = 0;
@ -139,7 +138,7 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::Run()
forEachGeometryItem( { PCB_PAD_T, PCB_VIA_T }, LSET::AllLayersMask(),
[&]( BOARD_ITEM* item ) -> bool
{
if( !reportProgress( ii++, count, delta ) )
if( !reportProgress( ii++, count, progressDelta ) )
return false;
if( item->Type() == PCB_PAD_T )
@ -162,7 +161,7 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::Run()
return true;
} );
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, int> checkedPairs;
std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
for( PCB_TRACK* track : m_board->Tracks() )
{
@ -171,7 +170,7 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::Run()
PCB_VIA* via = static_cast<PCB_VIA*>( track );
if( !reportProgress( ii++, count, delta ) )
if( !reportProgress( ii++, count, progressDelta ) )
return false; // DRC cancelled
// We only care about mechanically drilled (ie: non-laser) holes
@ -216,7 +215,7 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::Run()
{
for( PAD* pad : footprint->Pads() )
{
if( !reportProgress( ii++, count, delta ) )
if( !reportProgress( ii++, count, progressDelta ) )
return false; // DRC cancelled
// We only care about drilled (ie: round) holes

View File

@ -456,7 +456,7 @@ bool DRC_TEST_PROVIDER_LIBRARY_PARITY::Run()
FP_LIB_TABLE* libTable = project->PcbFootprintLibs();
wxString msg;
int ii = 0;
const int delta = 50; // Number of tests between calls to progress bar
const int progressDelta = 250;
if( !reportPhase( _( "Checking board footprints against library..." ) ) )
return false;
@ -469,7 +469,7 @@ bool DRC_TEST_PROVIDER_LIBRARY_PARITY::Run()
return true; // Continue with other tests
}
if( !reportProgress( ii++, board->Footprints().size(), delta ) )
if( !reportProgress( ii++, board->Footprints().size(), progressDelta ) )
return false; // DRC cancelled
LIB_ID fpID = footprint->GetFPID();

Some files were not shown because too many files have changed in this diff Show More