Replace wxTextFile for writing fp info cache

wxTextFile uses wxFile which uses write syscalls which means its unbuffered.
This makes file IO more expensive against network shares where it will flush far too aggressively.
wxTextFile is fine for reads however.
This commit is contained in:
Marek Roszko 2020-12-10 20:08:51 -05:00
parent 645c49427c
commit 0967995a80
5 changed files with 39 additions and 44 deletions

View File

@ -146,8 +146,7 @@ FOOTPRINT_LIST* FOOTPRINT_LIST::GetInstance( KIWAY& aKiway )
if( !footprintInfo->GetCount() )
{
wxTextFile footprintInfoCache( aKiway.Prj().GetProjectPath() + "fp-info-cache" );
footprintInfo->ReadCacheFromFile( &footprintInfoCache );
footprintInfo->ReadCacheFromFile( aKiway.Prj().GetProjectPath() + "fp-info-cache" );
}
return footprintInfo;

View File

@ -187,8 +187,8 @@ public:
{
}
virtual void WriteCacheToFile( wxTextFile* aFile ) { };
virtual void ReadCacheFromFile( wxTextFile* aFile ) { };
virtual void WriteCacheToFile( const wxString& aFilePath ) {};
virtual void ReadCacheFromFile( const wxString& aFilePath ){};
/**
* @return the number of items stored in list

View File

@ -35,6 +35,8 @@
#include <pgm_base.h>
#include <wildcards_and_files_ext.h>
#include <widgets/progress_reporter.h>
#include <wx/txtstrm.h>
#include <wx/wfstream.h>
#include <thread>
#include <mutex>
@ -339,59 +341,55 @@ FOOTPRINT_LIST_IMPL::~FOOTPRINT_LIST_IMPL()
}
void FOOTPRINT_LIST_IMPL::WriteCacheToFile( wxTextFile* aCacheFile )
void FOOTPRINT_LIST_IMPL::WriteCacheToFile( const wxString& aFilePath )
{
if( aCacheFile->Exists() )
{
if( !aCacheFile->Open() )
return;
wxFFileOutputStream outStream( aFilePath );
wxTextOutputStream txtStream( outStream );
aCacheFile->Clear();
}
else
if( !outStream.IsOk() )
{
if( !aCacheFile->Create() )
return;
return;
}
aCacheFile->AddLine( wxString::Format( "%lld", m_list_timestamp ) );
txtStream << wxString::Format( "%lld", m_list_timestamp ) << endl;
for( auto& fpinfo : m_list )
for( std::unique_ptr<FOOTPRINT_INFO>& fpinfo : m_list )
{
aCacheFile->AddLine( fpinfo->GetLibNickname() );
aCacheFile->AddLine( fpinfo->GetName() );
aCacheFile->AddLine( EscapeString( fpinfo->GetDescription(), CTX_LINE ) );
aCacheFile->AddLine( EscapeString( fpinfo->GetKeywords(), CTX_LINE ) );
aCacheFile->AddLine( wxString::Format( "%d", fpinfo->GetOrderNum() ) );
aCacheFile->AddLine( wxString::Format( "%u", fpinfo->GetPadCount() ) );
aCacheFile->AddLine( wxString::Format( "%u", fpinfo->GetUniquePadCount() ) );
txtStream << fpinfo->GetLibNickname() << endl;
txtStream << fpinfo->GetName() << endl;
txtStream << EscapeString( fpinfo->GetDescription(), CTX_LINE ) << endl;
txtStream << EscapeString( fpinfo->GetKeywords(), CTX_LINE ) << endl;
txtStream << wxString::Format( "%d", fpinfo->GetOrderNum() ) << endl;
txtStream << wxString::Format( "%u", fpinfo->GetPadCount() ) << endl;
txtStream << wxString::Format( "%u", fpinfo->GetUniquePadCount() ) << endl;
}
aCacheFile->Write();
aCacheFile->Close();
txtStream.Flush();
}
void FOOTPRINT_LIST_IMPL::ReadCacheFromFile( wxTextFile* aCacheFile )
void FOOTPRINT_LIST_IMPL::ReadCacheFromFile( const wxString& aFilePath )
{
wxTextFile cacheFile( aFilePath );
m_list_timestamp = 0;
m_list.clear();
try
{
if( aCacheFile->Exists() && aCacheFile->Open() )
if( cacheFile.Exists() && cacheFile.Open() )
{
aCacheFile->GetFirstLine().ToLongLong( &m_list_timestamp );
cacheFile.GetFirstLine().ToLongLong( &m_list_timestamp );
while( aCacheFile->GetCurrentLine() + 6 < aCacheFile->GetLineCount() )
while( cacheFile.GetCurrentLine() + 6 < cacheFile.GetLineCount() )
{
wxString libNickname = aCacheFile->GetNextLine();
wxString name = aCacheFile->GetNextLine();
wxString description = UnescapeString( aCacheFile->GetNextLine() );
wxString keywords = UnescapeString( aCacheFile->GetNextLine() );
int orderNum = wxAtoi( aCacheFile->GetNextLine() );
unsigned int padCount = (unsigned) wxAtoi( aCacheFile->GetNextLine() );
unsigned int uniquePadCount = (unsigned) wxAtoi( aCacheFile->GetNextLine() );
wxString libNickname = cacheFile.GetNextLine();
wxString name = cacheFile.GetNextLine();
wxString description = UnescapeString( cacheFile.GetNextLine() );
wxString keywords = UnescapeString( cacheFile.GetNextLine() );
int orderNum = wxAtoi( cacheFile.GetNextLine() );
unsigned int padCount = (unsigned) wxAtoi( cacheFile.GetNextLine() );
unsigned int uniquePadCount = (unsigned) wxAtoi( cacheFile.GetNextLine() );
auto* fpinfo = new FOOTPRINT_INFO_IMPL( libNickname, name, description, keywords,
orderNum, padCount, uniquePadCount );
@ -409,6 +407,6 @@ void FOOTPRINT_LIST_IMPL::ReadCacheFromFile( wxTextFile* aCacheFile )
if( m_list.size() == 0 )
m_list_timestamp = 0;
if( aCacheFile->IsOpened() )
aCacheFile->Close();
if( cacheFile.IsOpened() )
cacheFile.Close();
}

View File

@ -117,8 +117,8 @@ public:
FOOTPRINT_LIST_IMPL();
virtual ~FOOTPRINT_LIST_IMPL();
void WriteCacheToFile( wxTextFile* aFile ) override;
void ReadCacheFromFile( wxTextFile* aFile ) override;
void WriteCacheToFile( const wxString& aFilePath ) override;
void ReadCacheFromFile( const wxString& aFilePath ) override;
bool ReadFootprintFiles( FP_LIB_TABLE* aTable, const wxString* aNickname = nullptr,
PROGRESS_REPORTER* aProgressReporter = nullptr ) override;

View File

@ -52,8 +52,7 @@ PCB_BASE_EDIT_FRAME::PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent,
{
if( !GFootprintList.GetCount() )
{
wxTextFile footprintInfoCache( Prj().GetProjectPath() + "fp-info-cache" );
GFootprintList.ReadCacheFromFile( &footprintInfoCache );
GFootprintList.ReadCacheFromFile( Prj().GetProjectPath() + "fp-info-cache" );
}
}
@ -70,8 +69,7 @@ void PCB_BASE_EDIT_FRAME::doCloseWindow()
if( mgr->IsProjectOpen() && wxFileName::IsDirWritable( Prj().GetProjectPath() ) )
{
wxTextFile footprintInfoCache( Prj().GetProjectPath() + "fp-info-cache" );
GFootprintList.WriteCacheToFile( &footprintInfoCache );
GFootprintList.WriteCacheToFile( Prj().GetProjectPath() + "fp-info-cache" );
}
// Close the project if we are standalone, so it gets cleaned up properly