From 2bf73585ba5c3345a4cb66e9ba36bbf16f9f48c5 Mon Sep 17 00:00:00 2001 From: ispyisail Date: Wed, 14 Oct 2026 11:25:29 +1300 Subject: [PATCH] Open legacy projects faster: derive the project uuid without copying QETProject::derivedUuid() copied the whole file content to drop '\r', then copied it again to prepend the name prefix, before hashing. On a 263 MB project with embedded photos that took 2 s of a 21 s open. Hash the content in place, skipping '\r', and set the version 5 bits as QUuid::createUuidV5() does. The uuid is unchanged: same result as before on the 23 example projects, their CRLF copies, edge cases (empty, only '\r') and the 263 MB project, and a resave of that project is byte-identical. --- sources/qetproject.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/sources/qetproject.cpp b/sources/qetproject.cpp index ddd199fea..805ffae00 100644 --- a/sources/qetproject.cpp +++ b/sources/qetproject.cpp @@ -46,6 +46,7 @@ #include "qetversion.h" #include "undocommand/adddiagramcommand.h" +#include #include #include #include @@ -412,11 +413,25 @@ QUuid QETProject::derivedUuid(const QByteArray &content) static const QUuid project_namespace( QStringLiteral("{c8c75719-0fea-4b1c-9f4b-2dd179fb2f0c}")); - QByteArray normalized(content); - normalized.replace('\r', QByteArray()); - return QUuid::createUuidV5(project_namespace, - QByteArrayLiteral("qet-project-legacy\n") - + normalized); + //Same result as QUuid::createUuidV5(project_namespace, + //"qet-project-legacy\n" + content without '\r'), hashed in place : + //copying the content twice took 2 s of opening a 263 MB project. + QCryptographicHash hash(QCryptographicHash::Sha1); + hash.addData(project_namespace.toRfc4122()); + hash.addData(QByteArrayView("qet-project-legacy\n")); + const QByteArrayView view(content); + qsizetype start = 0; + while (start < view.size()) { + qsizetype cr = view.indexOf('\r', start); + if (cr < 0) + cr = view.size(); + hash.addData(view.sliced(start, cr - start)); + start = cr + 1; + } + QByteArray bytes = hash.result().left(16); + bytes[6] = char((bytes[6] & 0x0F) | 0x50); // version 5 + bytes[8] = char((bytes[8] & 0x3F) | 0x80); // RFC 4122 variant + return QUuid::fromRfc4122(bytes); } /**