Use binary search on Footprint Info list.

While it only improves footprint loading on the standard library
by about 6%, it will keep larger libraries from getting catastrophic.
This commit is contained in:
Jeff Young 2018-08-03 22:09:48 +01:00
parent 33fc74a04d
commit 9aaa235b7b
3 changed files with 20 additions and 20 deletions

View File

@ -67,8 +67,9 @@ public:
// A dummy constructor for use as a target in a binary search // A dummy constructor for use as a target in a binary search
FOOTPRINT_INFO_IMPL( const wxString& aFootprintName ) FOOTPRINT_INFO_IMPL( const wxString& aNickname, const wxString& aFootprintName )
{ {
m_nickname = aNickname;
m_fpname = aFootprintName; m_fpname = aFootprintName;
m_owner = nullptr; m_owner = nullptr;

View File

@ -56,24 +56,23 @@ void FP_TREE_MODEL_ADAPTER::AddLibraries()
std::vector<LIB_TREE_ITEM*> FP_TREE_MODEL_ADAPTER::getFootprints( const wxString& aLibName ) std::vector<LIB_TREE_ITEM*> FP_TREE_MODEL_ADAPTER::getFootprints( const wxString& aLibName )
{ {
std::vector<LIB_TREE_ITEM*> list; std::vector<LIB_TREE_ITEM*> libList;
bool found = false;
for( auto& footprint : GFootprintList.GetList() ) auto fullListStart = GFootprintList.GetList().begin();
{ auto fullListEnd = GFootprintList.GetList().end();
if( footprint->GetLibNickname() != aLibName ) std::unique_ptr<FOOTPRINT_INFO> dummy( new FOOTPRINT_INFO_IMPL( aLibName, wxEmptyString ) );
// List is sorted, so use a binary search to find the range of footnotes for our library
auto libBounds = std::equal_range( fullListStart, fullListEnd, dummy,
[]( const std::unique_ptr<FOOTPRINT_INFO>& a, const std::unique_ptr<FOOTPRINT_INFO>& b )
{ {
if( found ) return StrNumCmp( a->GetLibNickname(), b->GetLibNickname(), INT_MAX, true ) < 0;
return list; } );
else
continue;
}
found = true; for( auto i = libBounds.first; i != libBounds.second; ++i )
list.push_back( footprint.get() ); libList.push_back( i->get() );
}
return list; return libList;
} }

View File

@ -97,12 +97,12 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNode )
{ {
// Since the list is sorted we can use a binary search to speed up searches within // Since the list is sorted we can use a binary search to speed up searches within
// libraries with lots of footprints. // libraries with lots of footprints.
FOOTPRINT_INFO_IMPL dummy( (*nodeIt)->Name ); FOOTPRINT_INFO_IMPL dummy( wxEmptyString, (*nodeIt)->Name );
auto footprintIt = std::lower_bound( footprints.begin(), footprints.end(), &dummy, auto footprintIt = std::lower_bound( footprints.begin(), footprints.end(), &dummy,
[]( LIB_TREE_ITEM* a, LIB_TREE_ITEM* b ) []( LIB_TREE_ITEM* a, LIB_TREE_ITEM* b )
{ {
return a->GetName() < b->GetName(); return StrNumCmp( a->GetName(), b->GetName(), INT_MAX, true ) < 0;
} ); } );
if( footprintIt != footprints.end() && dummy.GetName() == (*footprintIt)->GetName() ) if( footprintIt != footprints.end() && dummy.GetName() == (*footprintIt)->GetName() )
{ {