From 90aab8e041cb98baf46d7f7d2ba6dc7a14cae43e Mon Sep 17 00:00:00 2001 From: PeterCJ Date: Wed, 3 Dec 2025 10:09:48 -0800 Subject: [PATCH] Model checking: use date instead of MD5 to improve the performance Change from MD5 to internal attribute Calculating MD5 is computationally/time expensive, so switch to using an attribute in the *.model.xml instead of calculating MD5. See comments here: https://github.com/notepad-plus-plus/notepad-plus-plus/commit/c64b81e3a37d044ee1136b3b9e0f9e19dff3a885#commitcomment-171869728 Close #17263 --- PowerEditor/Test/xmlValidator/langs.xsd | 1 + PowerEditor/Test/xmlValidator/theme.xsd | 1 + PowerEditor/src/Parameters.cpp | 49 +++++++++++++------------ PowerEditor/src/langs.model.xml | 2 +- PowerEditor/src/stylers.model.xml | 2 +- 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/PowerEditor/Test/xmlValidator/langs.xsd b/PowerEditor/Test/xmlValidator/langs.xsd index 20893623d..d1b742aca 100644 --- a/PowerEditor/Test/xmlValidator/langs.xsd +++ b/PowerEditor/Test/xmlValidator/langs.xsd @@ -54,6 +54,7 @@ + diff --git a/PowerEditor/Test/xmlValidator/theme.xsd b/PowerEditor/Test/xmlValidator/theme.xsd index f15e9a6ed..8dc2a7374 100644 --- a/PowerEditor/Test/xmlValidator/theme.xsd +++ b/PowerEditor/Test/xmlValidator/theme.xsd @@ -97,6 +97,7 @@ + diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 3d6893eb1..355578058 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -25,7 +25,6 @@ #include "UserDefineDialog.h" #include "Notepad_plus_Window.h" #include "NppConstants.h" -#include "md5.h" #ifdef _MSC_VER #pragma warning(disable : 4996) // for GetVersionEx() @@ -2003,31 +2002,34 @@ void NppParameters::updateFromModelXml(TiXmlNode* rootUser, ConfXml whichConf) return; } - // now that the model is reasonable, it's reasonable to do the MD5-checking - MD5 md5; - std::string md5digest_model = md5.digestFile(sModelPath.c_str()); - std::wstring wsDigest = string2wstring(md5digest_model, CP_UTF8); - - std::string sUserText; - pXmlDocument->Print(sUserText); - std::string md5digest_user_text_before = md5.digestString(sUserText.c_str()); - - // if modelMD5 is the same as the one seen in the XML, don't need to merge in the model... + // compare the *.model.xml's modelDate to that of the active XML + const wchar_t* wc_model_modelDate = rootModel->Attribute(L"modelDate"); TiXmlElement* peRootUser = rootUser->ToElement(); - const wchar_t* pwct_modelMD5 = peRootUser->Attribute(L"modelMD5"); - std::string s_modelMD5_from_xml = wstring2string(pwct_modelMD5 ? pwct_modelMD5 : L"\n", CP_UTF8); - s_modelMD5_from_xml.pop_back(); // remove the NULL-terminator - if (md5digest_model == s_modelMD5_from_xml) + const wchar_t* wc_user_modelDate = peRootUser->Attribute(L"modelDate"); + + // if both attributes exist, compare the integers to decide to exit if integer(user) >= integer(model), + // because then the user file is at least as new as the model, and doesn't need to be updated; + // if they don't both exist, need to do the update, because there aren't any dates to compare + if (wc_model_modelDate && wc_user_modelDate) { - delete pXmlModel; - return; + int v_model = decStrVal(wc_model_modelDate); + int v_user = decStrVal(wc_user_modelDate); + if (v_user >= v_model) + { + delete pXmlModel; + return; + } } - // update (or add) the MD5 stored in the XML - peRootUser->SetAttribute(L"modelMD5", wsDigest.c_str()); + // get the current version of the text of the user file (used later to see if user file needs to be saved because of changes) + std::string sUserTextBefore; + pXmlDocument->Print(sUserTextBefore); + + // update (or add) the modelDate stored in the active XML (unless it's missing) + if (wc_model_modelDate) + peRootUser->SetAttribute(L"modelDate", wc_model_modelDate); // get the main internal element from both user and model - TiXmlElement* mainElemUser = rootUser->FirstChildElement(mainElementName); TiXmlElement* mainElemModel = rootModel->FirstChildElement(mainElementName); if (!mainElemUser || !mainElemModel) @@ -2051,10 +2053,9 @@ void NppParameters::updateFromModelXml(TiXmlNode* rootUser, ConfXml whichConf) } // check the user-langs document for changes - sUserText = ""; - pXmlDocument->Print(sUserText); - std::string md5digest_user_text_after = md5.digestString(sUserText.c_str()); - if (md5digest_user_text_before != md5digest_user_text_after) + std::string sUserTextAfter; + pXmlDocument->Print(sUserTextAfter); + if (sUserTextBefore != sUserTextAfter) { switch (whichConf) { diff --git a/PowerEditor/src/langs.model.xml b/PowerEditor/src/langs.model.xml index a8eb81431..7c8dc5c8d 100644 --- a/PowerEditor/src/langs.model.xml +++ b/PowerEditor/src/langs.model.xml @@ -1,5 +1,5 @@ - + diff --git a/PowerEditor/src/stylers.model.xml b/PowerEditor/src/stylers.model.xml index 86e5e6dba..ecd27a494 100644 --- a/PowerEditor/src/stylers.model.xml +++ b/PowerEditor/src/stylers.model.xml @@ -1,5 +1,5 @@ - +