Speed up footprint loading by caching

Store the COMPOUND_FILEs in a map referenced to the library name.  This
keeps the COMPOUND_FILE cache in memory rather than regenerating it each
time
This commit is contained in:
Seth Hillbrand 2023-08-31 14:46:15 -07:00
parent 1b63d11adf
commit 1662f6aad6
2 changed files with 36 additions and 8 deletions

View File

@ -153,15 +153,26 @@ void ALTIUM_DESIGNER_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames
const wxString& aLibraryPath, bool aBestEfforts, const wxString& aLibraryPath, bool aBestEfforts,
const STRING_UTF8_MAP* aProperties ) const STRING_UTF8_MAP* aProperties )
{ {
ALTIUM_COMPOUND_FILE altiumLibFile( aLibraryPath ); ALTIUM_COMPOUND_FILE* altiumLibFile = nullptr;
auto it = m_fplibFiles.find( aLibraryPath );
if( it == m_fplibFiles.end() )
{
auto new_it = m_fplibFiles.emplace( aLibraryPath, std::make_unique<ALTIUM_COMPOUND_FILE>( aLibraryPath ) );
altiumLibFile = new_it.first->second.get();
}
else
{
altiumLibFile = it->second.get();
}
try try
{ {
// Map code-page-dependent names to unicode names // Map code-page-dependent names to unicode names
std::map<wxString, wxString> patternMap = altiumLibFile.ListLibFootprints(); std::map<wxString, wxString> patternMap = altiumLibFile->ListLibFootprints();
const std::vector<std::string> streamName = { "Library", "Data" }; const std::vector<std::string> streamName = { "Library", "Data" };
const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile.FindStream( streamName ); const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile->FindStream( streamName );
if( libraryData == nullptr ) if( libraryData == nullptr )
{ {
@ -169,7 +180,7 @@ void ALTIUM_DESIGNER_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames
wxString::Format( _( "File not found: '%s'." ), FormatPath( streamName ) ) ); wxString::Format( _( "File not found: '%s'." ), FormatPath( streamName ) ) );
} }
ALTIUM_PARSER parser( altiumLibFile, libraryData ); ALTIUM_PARSER parser( *altiumLibFile, libraryData );
std::map<wxString, wxString> properties = parser.ReadProperties(); std::map<wxString, wxString> properties = parser.ReadProperties();
@ -218,13 +229,24 @@ FOOTPRINT* ALTIUM_DESIGNER_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
const wxString& aFootprintName, bool aKeepUUID, const wxString& aFootprintName, bool aKeepUUID,
const STRING_UTF8_MAP* aProperties ) const STRING_UTF8_MAP* aProperties )
{ {
ALTIUM_COMPOUND_FILE altiumLibFile( aLibraryPath ); ALTIUM_COMPOUND_FILE* altiumLibFile = nullptr;
auto it = m_fplibFiles.find( aLibraryPath );
if( it == m_fplibFiles.end() )
{
auto new_it = m_fplibFiles.emplace( aLibraryPath, std::make_unique<ALTIUM_COMPOUND_FILE>( aLibraryPath ) );
altiumLibFile = new_it.first->second.get();
}
else
{
altiumLibFile = it->second.get();
}
try try
{ {
// Parse File // Parse File
ALTIUM_PCB pcb( m_board, nullptr ); ALTIUM_PCB pcb( m_board, nullptr );
return pcb.ParseFootprint( altiumLibFile, aFootprintName ); return pcb.ParseFootprint( *altiumLibFile, aFootprintName );
} }
catch( CFB::CFBException& exception ) catch( CFB::CFBException& exception )
{ {

View File

@ -25,9 +25,13 @@
#ifndef ALTIUM_DESIGNER_PLUGIN_H_ #ifndef ALTIUM_DESIGNER_PLUGIN_H_
#define ALTIUM_DESIGNER_PLUGIN_H_ #define ALTIUM_DESIGNER_PLUGIN_H_
#include <io_mgr.h> #include <io_mgr.h>
#include <map>
#include <memory>
class ALTIUM_COMPOUND_FILE;
class ALTIUM_DESIGNER_PLUGIN : public PLUGIN class ALTIUM_DESIGNER_PLUGIN : public PLUGIN
{ {
public: public:
@ -75,6 +79,8 @@ public:
private: private:
const STRING_UTF8_MAP* m_props; const STRING_UTF8_MAP* m_props;
BOARD* m_board; BOARD* m_board;
std::map<wxString, std::unique_ptr<ALTIUM_COMPOUND_FILE>> m_fplibFiles;
}; };
#endif // ALTIUM_DESIGNER_PLUGIN_H_ #endif // ALTIUM_DESIGNER_PLUGIN_H_