Performance optimizations for database libraries.

This commit is contained in:
Alex Shvartzkop 2024-02-19 23:45:24 +03:00 committed by dsa-t
parent 3e26e7b646
commit e68df8e1d1
8 changed files with 106 additions and 54 deletions

View File

@ -448,7 +448,7 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
{
aResult[column] = fmt::format( "{:G}", results.get<double>( i ) );
}
catch( nanodbc::null_access_error& e )
catch( nanodbc::null_access_error& )
{
// Column was empty (null)
aResult[column] = std::string();
@ -498,6 +498,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
{
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - cache hit" ), aTable );
aResults.reserve( cacheEntry.size() );
for( auto &[ key, row ] : cacheEntry )
aResults.emplace_back( row );
@ -605,7 +607,7 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
{
result[column] = fmt::format( "{:G}", results.get<double>( j ) );
}
catch( nanodbc::null_access_error& e )
catch( nanodbc::null_access_error& )
{
// Column was empty (null)
result[column] = std::string();

View File

@ -32,6 +32,17 @@
const int dblibSchemaVersion = 1;
DATABASE_FIELD_MAPPING::DATABASE_FIELD_MAPPING( std::string aColumn, std::string aName,
bool aVisibleOnAdd, bool aVisibleInChooser,
bool aShowName, bool aInheritProperties ) :
column( aColumn ),
name( aName ), name_wx( aName.c_str(), wxConvUTF8 ), visible_on_add( aVisibleOnAdd ),
visible_in_chooser( aVisibleInChooser ), show_name( aShowName ),
inherit_properties( aInheritProperties )
{
}
DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
JSON_SETTINGS( aFilename, SETTINGS_LOC::NONE, dblibSchemaVersion )
{
@ -113,11 +124,8 @@ DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
bool inherit = fetchOrDefault<bool>( fieldJson, "inherit_properties" );
table.fields.emplace_back(
DATABASE_FIELD_MAPPING(
{
column, name, visible_on_add, visible_in_chooser, show_name,
inherit
} ) );
DATABASE_FIELD_MAPPING( column, name, visible_on_add,
visible_in_chooser, show_name, inherit ) );
}
}

View File

@ -313,40 +313,40 @@ wxString UnescapeString( const wxString& aSource )
}
else
{
token.append( ch );
token << ch;
}
}
if( !terminated )
{
newbuf.append( wxT( "{" ) + UnescapeString( token ) );
newbuf << wxT( "{" ) << UnescapeString( token );
}
else if( prev == '$' || prev == '~' || prev == '^' || prev == '_' )
{
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
newbuf << wxT( "{" ) << UnescapeString( token ) << wxT( "}" );
}
else if( token == wxT( "dblquote" ) ) newbuf.append( wxT( "\"" ) );
else if( token == wxT( "quote" ) ) newbuf.append( wxT( "'" ) );
else if( token == wxT( "lt" ) ) newbuf.append( wxT( "<" ) );
else if( token == wxT( "gt" ) ) newbuf.append( wxT( ">" ) );
else if( token == wxT( "backslash" ) ) newbuf.append( wxT( "\\" ) );
else if( token == wxT( "slash" ) ) newbuf.append( wxT( "/" ) );
else if( token == wxT( "bar" ) ) newbuf.append( wxT( "|" ) );
else if( token == wxT( "comma" ) ) newbuf.append( wxT( "," ) );
else if( token == wxT( "colon" ) ) newbuf.append( wxT( ":" ) );
else if( token == wxT( "space" ) ) newbuf.append( wxT( " " ) );
else if( token == wxT( "dollar" ) ) newbuf.append( wxT( "$" ) );
else if( token == wxT( "tab" ) ) newbuf.append( wxT( "\t" ) );
else if( token == wxT( "return" ) ) newbuf.append( wxT( "\n" ) );
else if( token == wxT( "brace" ) ) newbuf.append( wxT( "{" ) );
else if( token == wxT( "dblquote" ) ) newbuf << wxT( "\"" );
else if( token == wxT( "quote" ) ) newbuf << wxT( "'" );
else if( token == wxT( "lt" ) ) newbuf << wxT( "<" );
else if( token == wxT( "gt" ) ) newbuf << wxT( ">" );
else if( token == wxT( "backslash" ) ) newbuf << wxT( "\\" );
else if( token == wxT( "slash" ) ) newbuf << wxT( "/" );
else if( token == wxT( "bar" ) ) newbuf << wxT( "|" );
else if( token == wxT( "comma" ) ) newbuf << wxT( "," );
else if( token == wxT( "colon" ) ) newbuf << wxT( ":" );
else if( token == wxT( "space" ) ) newbuf << wxT( " " );
else if( token == wxT( "dollar" ) ) newbuf << wxT( "$" );
else if( token == wxT( "tab" ) ) newbuf << wxT( "\t" );
else if( token == wxT( "return" ) ) newbuf << wxT( "\n" );
else if( token == wxT( "brace" ) ) newbuf << wxT( "{" );
else
{
newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
newbuf << wxT( "{" ) << UnescapeString( token ) << wxT( "}" );
}
}
else
{
newbuf.append( ch );
newbuf << ch;
}
}
@ -785,11 +785,14 @@ int StrNumCmp( const wxString& aString1, const wxString& aString2, bool aIgnoreC
// Any numerical comparisons to here are identical.
if( aIgnoreCase )
{
if( wxToupper( c1 ) < wxToupper( c2 ) )
return -1;
if( c1 != c2 )
{
wxUniChar uc1 = wxToupper( c1 );
wxUniChar uc2 = wxToupper( c2 );
if( wxToupper( c1 ) > wxToupper( c2 ) )
return 1;
if( uc1 != uc2 )
return uc1 < uc2 ? -1 : 1;
}
}
else
{

View File

@ -54,8 +54,16 @@ const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTra
case FOOTPRINT_FIELD: return s_CanonicalFootprint; // The footprint for use with Pcbnew
case DATASHEET_FIELD: return s_CanonicalDatasheet; // Link to a datasheet for symbol
case DESCRIPTION_FIELD: return s_CanonicalDescription; // The symbol description
default: return wxString::Format( wxT( "Field%d" ), aFieldNdx );
default: break;
}
wxString str( wxS( "Field" ) );
#if wxUSE_UNICODE_WCHAR
str << std::to_wstring( aFieldNdx );
#else
str << std::to_string( aFieldNdx );
#endif
return str;
}
switch( aFieldNdx )

View File

@ -568,6 +568,9 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
for( LIB_FIELD* field : fields )
fieldsMap[field->GetName()] = field;
static const wxString c_valueFieldName( wxS( "Value" ) );
static const wxString c_datasheetFieldName( wxS( "Datasheet" ) );
for( const DATABASE_FIELD_MAPPING& mapping : aTable.fields )
{
if( !aRow.count( mapping.column ) )
@ -577,7 +580,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
continue;
}
std:: string strValue;
std::string strValue;
try
{
@ -589,7 +592,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
wxString value( strValue.c_str(), wxConvUTF8 );
if( mapping.name == wxT( "Value" ) )
if( mapping.name_wx == c_valueFieldName )
{
LIB_FIELD& field = symbol->GetValueField();
field.SetText( value );
@ -601,7 +604,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
}
continue;
}
else if( mapping.name == wxT( "Datasheet" ) )
else if( mapping.name_wx == c_datasheetFieldName )
{
LIB_FIELD& field = symbol->GetDatasheetField();
field.SetText( value );
@ -621,16 +624,16 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
LIB_FIELD* field;
bool isNew = false;
if( fieldsMap.count( mapping.name ) )
if( fieldsMap.count( mapping.name_wx ) )
{
field = fieldsMap[mapping.name];
field = fieldsMap[mapping.name_wx];
}
else
{
field = new LIB_FIELD( symbol->GetNextAvailableFieldId() );
field->SetName( mapping.name );
field->SetName( mapping.name_wx );
isNew = true;
fieldsMap[mapping.name] = field;
fieldsMap[mapping.name_wx] = field;
}
if( !mapping.inherit_properties || isNew )
@ -643,13 +646,15 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
field->SetText( value );
if( isNew )
symbol->AddField( field );
symbol->AddDrawItem( field, false );
m_customFields.insert( mapping.name );
m_customFields.insert( mapping.name_wx );
if( mapping.visible_in_chooser )
m_defaultShownFields.insert( mapping.name );
m_defaultShownFields.insert( mapping.name_wx );
}
symbol->GetDrawItems().sort();
return symbol;
}

View File

@ -1644,12 +1644,21 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
wxString prefix = aSymbol.GetPrefix();
T_field* valueField = aSymbol.FindField( wxT( "Value" ) );
std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
bool sourcePinsSorted = false;
std::sort( sourcePins.begin(), sourcePins.end(),
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
{
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
} );
auto lazySortSourcePins = [&sourcePins, &sourcePinsSorted]()
{
if( !sourcePinsSorted )
{
std::sort( sourcePins.begin(), sourcePins.end(),
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
{
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
} );
}
sourcePinsSorted = true;
};
FIELD_INFO deviceInfo;
FIELD_INFO modelInfo;
@ -1740,6 +1749,8 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
wxStringSplit( legacyPins->GetText(), pinIndexes, ' ' );
lazySortSourcePins();
if( isPassive && pinIndexes.size() == 2 && sourcePins.size() == 2 )
{
if( pinIndexes[0] == wxT( "2" ) )
@ -1800,6 +1811,8 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
model = model.BeforeFirst( ' ', &modelLineParams );
modelInfo.m_Text = model;
lazySortSourcePins();
SIM_LIBRARY::MODEL simModel = libMgr.CreateModel( lib, model.ToStdString(),
emptyFields, sourcePins, reporter );
@ -1873,6 +1886,8 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
if( pinMapInfo.IsEmpty() )
{
lazySortSourcePins();
// Generate a default pin map from the SIM_MODEL's pins
simModel->createPins( sourcePins );
pinMapInfo.m_Text = wxString( simModel->Serializer().GeneratePins() );
@ -1979,7 +1994,10 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
// the default pin map from the symbol's pins.
if( pinMapInfo.IsEmpty() )
{
lazySortSourcePins();
pinMapInfo.m_Text = generateDefaultPinMapFromSymbol( sourcePins );
}
}
if( !pinMapInfo.IsEmpty() )

View File

@ -163,13 +163,15 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
if( !parentDesc.IsEmpty() )
desc = wxString::Format( wxT( "%s (%s)" ), parentDesc, lib );
UTF8 utf8Lib( lib );
std::vector<LIB_SYMBOL*> symbols;
std::copy_if( libSymbols.begin(), libSymbols.end(),
std::back_inserter( symbols ),
[&lib]( LIB_SYMBOL* aSym )
[&utf8Lib]( LIB_SYMBOL* aSym )
{
return lib.IsSameAs( aSym->GetLibId().GetSubLibraryName() );
return utf8Lib == aSym->GetLibId().GetSubLibraryName();
} );
addFunc( name, symbols, desc );

View File

@ -22,6 +22,7 @@
#define KICAD_DATABASE_LIB_SETTINGS_H
#include <settings/json_settings.h>
#include <wx/string.h>
enum class DATABASE_SOURCE_TYPE
@ -44,12 +45,17 @@ struct DATABASE_SOURCE
struct DATABASE_FIELD_MAPPING
{
std::string column; ///< Database column name
std::string name; ///< KiCad field name
bool visible_on_add; ///< Whether to show the field when placing the symbol
bool visible_in_chooser; ///< Whether the column is shown by default in the chooser
bool show_name; ///< Whether or not to show the field name as well as its value
bool inherit_properties; ///< Whether or not to inherit properties from symbol field
const std::string column; ///< Database column name
const std::string name; ///< KiCad field name
const wxString name_wx; ///< KiCad field name (converted)
const bool visible_on_add; ///< Whether to show the field when placing the symbol
const bool visible_in_chooser; ///< Whether the column is shown by default in the chooser
const bool show_name; ///< Whether or not to show the field name as well as its value
const bool inherit_properties; ///< Whether or not to inherit properties from symbol field
explicit DATABASE_FIELD_MAPPING( std::string aColumn, std::string aName, bool aVisibleOnAdd,
bool aVisibleInChooser, bool aShowName,
bool aInheritProperties );
};