Rebuild the project database once per load instead of once per table model

ProjectDBModel::setQuery() calls projectDataBase::updateDB(), which drops
and repopulates every table in the database. The rebuild does not depend on
the query, so each table model that queries the database while a project is
being read triggers another complete repopulate of the same content.
Opening a 100 folio project ran updateDB() 26 times, 9.9 s of a 15.7 s load.

Two changes, because the first alone is not enough:

setUpdateBlocked() lets a bulk operation suppress the rebuild and do it
once when it is done. readProjectXml() already wrapped the load in
blockSignals(true) "to avoid hundreds of unnecessary emitted signal", but
that suppresses only the signal, not the work it announces; this extends
the same intent to the work. Both early returns in readProjectXml() sit
before the block, so no path leaves the database permanently blocked.

Further rebuilds are triggered after readProjectXml() returns, where the
load phase timers cannot see them -- with only the block in place
updateDB() still ran 5 times on examples/industrial.qet. So the database
now also tracks whether anything has changed since the last rebuild, and
skips repopulating when nothing has. dataBaseUpdated() is still emitted in
that case: callers and models rely on it to refresh, and what they read
back is the same either way. Every method of the class that writes rows
marks the flag; from outside, the database is reachable only through
newQuery(), and all five call sites read.

Repeating the rebuild was wasteful rather than wrong -- each
populate*Table() begins with a DELETE -- so this changes no output.
Verified byte identical --info on all 23 example projects, and identical
--export-bom, --export-wires, --export-cables, --export-nets and
--export-wiring on industrial.qet. Its load drops from 5.51 s to 5.31 s
(median of 6).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6MRq2Ach1ogvnGcbuqNLr
This commit is contained in:
ispyisail
2026-09-12 13:50:24 +12:00
parent 2c88f78f69
commit 956836458a
3 changed files with 64 additions and 0 deletions
+17
View File
@@ -47,6 +47,17 @@ class projectDataBase : public QObject
virtual ~projectDataBase() override;
void updateDB();
/**
Suppress the full rebuild performed by updateDB().
While blocked, updateDB() returns immediately instead of
repopulating every table. Meant for bulk operations -- notably
loading a project, where each table model re-queries the
database as it is built and would otherwise trigger one
complete rebuild of it. The caller unblocks and calls
updateDB() once when done; @see QETProject::readProjectXml().
*/
void setUpdateBlocked(bool blocked);
QETProject *project() const;
QSqlQuery newQuery(const QString &query = QString());
QSqlDatabase database() const {return m_data_base;}
@@ -97,6 +108,12 @@ class projectDataBase : public QObject
private:
QPointer<QETProject> m_project;
bool m_update_blocked = false;
//Starts true : the database is empty until the first rebuild.
//Set by every method of this class that writes rows, cleared by
//updateDB(). Callers reach the database from outside only through
//newQuery(), and every such call site reads.
bool m_content_changed = true;
QSqlDatabase m_data_base;
QSqlQuery m_insert_elements_query,
m_insert_element_info_query,