Add a cache for looking up board items by ID

This commit is contained in:
Jon Evans 2024-03-25 21:58:02 -04:00
parent 7b6afd290a
commit 5aa8af1abf
3 changed files with 72 additions and 4 deletions

View File

@ -228,4 +228,12 @@ KICOMMON_API void to_json( nlohmann::json& aJson, const KIID& aKIID );
KICOMMON_API void from_json( const nlohmann::json& aJson, KIID& aKIID ); KICOMMON_API void from_json( const nlohmann::json& aJson, KIID& aKIID );
template<> struct KICOMMON_API std::hash<KIID>
{
std::size_t operator()( const KIID& aId ) const
{
return aId.Hash();
}
};
#endif // KIID_H #endif // KIID_H

View File

@ -149,6 +149,8 @@ BOARD::~BOARD()
item->SetParentGroup( nullptr ); item->SetParentGroup( nullptr );
} }
m_itemByIdCache.clear();
// Clean up the owned elements // Clean up the owned elements
DeleteMARKERs(); DeleteMARKERs();
@ -896,6 +898,8 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity
return; return;
} }
m_itemByIdCache.insert( { aBoardItem->m_Uuid, aBoardItem } );
switch( aBoardItem->Type() ) switch( aBoardItem->Type() )
{ {
case PCB_NETINFO_T: case PCB_NETINFO_T:
@ -941,12 +945,20 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity
break; break;
case PCB_FOOTPRINT_T: case PCB_FOOTPRINT_T:
if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND ) {
m_footprints.push_back( static_cast<FOOTPRINT*>( aBoardItem ) ); FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aBoardItem );
else
m_footprints.push_front( static_cast<FOOTPRINT*>( aBoardItem ) );
if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
m_footprints.push_back( footprint );
else
m_footprints.push_front( footprint );
footprint->RunOnChildren( [&]( BOARD_ITEM* aChild )
{
m_itemByIdCache.insert( { aChild->m_Uuid, aChild } );
} );
break; break;
}
case PCB_DIM_ALIGNED_T: case PCB_DIM_ALIGNED_T:
case PCB_DIM_CENTER_T: case PCB_DIM_CENTER_T:
@ -960,12 +972,24 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity
case PCB_TEXTBOX_T: case PCB_TEXTBOX_T:
case PCB_TABLE_T: case PCB_TABLE_T:
case PCB_TARGET_T: case PCB_TARGET_T:
{
if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND ) if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
m_drawings.push_back( aBoardItem ); m_drawings.push_back( aBoardItem );
else else
m_drawings.push_front( aBoardItem ); m_drawings.push_front( aBoardItem );
if( aBoardItem->Type() == PCB_TABLE_T )
{
PCB_TABLE* table = static_cast<PCB_TABLE*>( aBoardItem );
table->RunOnChildren( [&]( BOARD_ITEM* aChild )
{
m_itemByIdCache.insert( { aChild->m_Uuid, aChild } );
} );
}
break; break;
}
// other types may use linked list // other types may use linked list
default: default:
@ -1009,6 +1033,8 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
// find these calls and fix them! Don't send me no stinking' nullptr. // find these calls and fix them! Don't send me no stinking' nullptr.
wxASSERT( aBoardItem ); wxASSERT( aBoardItem );
m_itemByIdCache.erase( aBoardItem->m_Uuid );
switch( aBoardItem->Type() ) switch( aBoardItem->Type() )
{ {
case PCB_NETINFO_T: case PCB_NETINFO_T:
@ -1043,8 +1069,17 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
break; break;
case PCB_FOOTPRINT_T: case PCB_FOOTPRINT_T:
{
alg::delete_matching( m_footprints, aBoardItem ); alg::delete_matching( m_footprints, aBoardItem );
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aBoardItem );
footprint->RunOnChildren( [&]( BOARD_ITEM* aChild )
{
m_itemByIdCache.erase( aChild->m_Uuid );
} );
break; break;
}
case PCB_TRACE_T: case PCB_TRACE_T:
case PCB_ARC_T: case PCB_ARC_T:
@ -1064,8 +1099,21 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
case PCB_TEXTBOX_T: case PCB_TEXTBOX_T:
case PCB_TABLE_T: case PCB_TABLE_T:
case PCB_TARGET_T: case PCB_TARGET_T:
{
alg::delete_matching( m_drawings, aBoardItem ); alg::delete_matching( m_drawings, aBoardItem );
if( aBoardItem->Type() == PCB_TABLE_T )
{
PCB_TABLE* table = static_cast<PCB_TABLE*>( aBoardItem );
table->RunOnChildren( [&]( BOARD_ITEM* aChild )
{
m_itemByIdCache.erase( aChild->m_Uuid );
} );
}
break; break;
}
// other types may use linked list // other types may use linked list
default: default:
@ -1166,6 +1214,9 @@ void BOARD::RemoveAll( std::initializer_list<KICAD_T> aTypes )
} }
} }
for( BOARD_ITEM* item : removed )
m_itemByIdCache.erase( item->m_Uuid );
FinalizeBulkRemove( removed ); FinalizeBulkRemove( removed );
} }
@ -1239,7 +1290,10 @@ void BOARD::DeleteAllFootprints()
m_skipMaxClearanceCacheUpdate = true; m_skipMaxClearanceCacheUpdate = true;
for( FOOTPRINT* footprint : m_footprints ) for( FOOTPRINT* footprint : m_footprints )
{
m_itemByIdCache.erase( footprint->m_Uuid );
delete footprint; delete footprint;
}
m_footprints.clear(); m_footprints.clear();
m_skipMaxClearanceCacheUpdate = false; m_skipMaxClearanceCacheUpdate = false;
@ -1252,6 +1306,9 @@ BOARD_ITEM* BOARD::GetItem( const KIID& aID ) const
if( aID == niluuid ) if( aID == niluuid )
return nullptr; return nullptr;
if( m_itemByIdCache.count( aID ) )
return m_itemByIdCache.at( aID );
for( PCB_TRACK* track : Tracks() ) for( PCB_TRACK* track : Tracks() )
{ {
if( track->m_Uuid == aID ) if( track->m_Uuid == aID )

View File

@ -1290,6 +1290,9 @@ private:
ZONES m_zones; ZONES m_zones;
GENERATORS m_generators; GENERATORS m_generators;
// Cache for fast access to items in the containers above by KIID, including children
std::unordered_map<KIID, BOARD_ITEM*> m_itemByIdCache;
LAYER m_layers[PCB_LAYER_ID_COUNT]; LAYER m_layers[PCB_LAYER_ID_COUNT];
HIGH_LIGHT_INFO m_highLight; // current high light data HIGH_LIGHT_INFO m_highLight; // current high light data