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
FOOTPRINT_INFO_IMPL( const wxString& aFootprintName )
FOOTPRINT_INFO_IMPL( const wxString& aNickname, const wxString& aFootprintName )
{
m_nickname = aNickname;
m_fpname = aFootprintName;
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*> list;
bool found = false;
std::vector<LIB_TREE_ITEM*> libList;
for( auto& footprint : GFootprintList.GetList() )
{
if( footprint->GetLibNickname() != aLibName )
auto fullListStart = GFootprintList.GetList().begin();
auto fullListEnd = GFootprintList.GetList().end();
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 list;
else
continue;
}
return StrNumCmp( a->GetLibNickname(), b->GetLibNickname(), INT_MAX, true ) < 0;
} );
found = true;
list.push_back( footprint.get() );
}
for( auto i = libBounds.first; i != libBounds.second; ++i )
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
// 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,
[]( LIB_TREE_ITEM* a, LIB_TREE_ITEM* b )
{
return a->GetName() < b->GetName();
} );
[]( LIB_TREE_ITEM* a, LIB_TREE_ITEM* b )
{
return StrNumCmp( a->GetName(), b->GetName(), INT_MAX, true ) < 0;
} );
if( footprintIt != footprints.end() && dummy.GetName() == (*footprintIt)->GetName() )
{