include/svl/itemset.hxx | 1 + sc/inc/patattr.hxx | 3 +++ sc/source/core/data/patattr.cxx | 14 +++++++++++++- svl/source/items/itemset.cxx | 19 +++++++++++++++++++ uitest/uitest/test.py | 4 ++-- vcl/source/control/listbox.cxx | 2 ++ 6 files changed, 40 insertions(+), 3 deletions(-)
New commits: commit b1df5786458223f21f0eaa9627c0f4c6fa5f1747 Author: Noel Grandin <[email protected]> AuthorDate: Sun Dec 21 19:55:04 2025 +0200 Commit: Noel Grandin <[email protected]> CommitDate: Thu Jan 1 09:10:56 2026 +0100 tdf#166684 use hashing in CellAttributeHelper::registerAndCheck reduces load time from 1m11s to 33s. Change-Id: I911c101eb8692bf678e6f7147e64e503e9f2bf0a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196062 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Tomaž Vajngerl <[email protected]> (cherry picked from commit 044885e896a441c96a6934b10cbb723fabcf262d) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196357 Reviewed-by: Noel Grandin <[email protected]> Tested-by: Jenkins diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx index 118e3da7f036..7dd32ff77791 100644 --- a/include/svl/itemset.hxx +++ b/include/svl/itemset.hxx @@ -246,6 +246,7 @@ public: const SfxItemSet* GetParent() const { return m_pParent; } bool operator==(const SfxItemSet &) const; + size_t GetHashCode() const; /** Compare possibly ignoring SfxItemPool pointer. diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx index f08c29710267..1bcc5675b6bb 100644 --- a/sc/inc/patattr.hxx +++ b/sc/inc/patattr.hxx @@ -130,6 +130,7 @@ class SAL_DLLPUBLIC_RTTI ScPatternAttr final friend class CellAttributeHelper; SfxItemSet maLocalSfxItemSet; + mutable std::optional<size_t> moHashCode; std::optional<OUString> moName; mutable std::optional<bool> mxVisible; mutable std::optional<sal_uInt32> mxNumberFormatKey; @@ -149,6 +150,7 @@ public: SC_DLLPUBLIC ~ScPatternAttr(); bool operator==(const ScPatternAttr& rCmp) const; + size_t GetHashCode() const { if (!moHashCode) CalcHashCode(); return *moHashCode; } // version that allows nullptrs SC_DLLPUBLIC static bool areSame(const ScPatternAttr* pItem1, const ScPatternAttr* pItem2); @@ -285,6 +287,7 @@ private: LanguageType GetLanguageType() const; void InvalidateCaches(); void InvalidateCacheFor(sal_uInt16 nWhich); + void CalcHashCode() const; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx index 6f14db0c8c0c..e4e3587c807d 100644 --- a/sc/source/core/data/patattr.cxx +++ b/sc/source/core/data/patattr.cxx @@ -115,12 +115,14 @@ const ScPatternAttr* CellAttributeHelper::registerAndCheck(const ScPatternAttr& } const OUString* pCandidateStyleName = rCandidate.GetStyleName(); auto it = maRegisteredCellAttributes.lower_bound(pCandidateStyleName); + const size_t nCandidateHashCode = rCandidate.GetHashCode(); for (; it != maRegisteredCellAttributes.end(); ++it) { const ScPatternAttr* pCheck = *it; if (CompareStringPtr(pCheck->GetStyleName(), pCandidateStyleName) != 0) break; - if (ScPatternAttr::areSame(pCheck, &rCandidate)) + if (nCandidateHashCode == pCheck->GetHashCode() + && ScPatternAttr::areSame(pCheck, &rCandidate)) { pCheck->mnRefCount++; if (bPassingOwnership) @@ -472,6 +474,15 @@ bool ScPatternAttr::operator==(const ScPatternAttr& rCmp) const return maLocalSfxItemSet == rCmp.maLocalSfxItemSet; } +void ScPatternAttr::CalcHashCode() const +{ + size_t nHash = 0; + if (const OUString* pName = GetStyleName()) + nHash = pName->hashCode(); + o3tl::hash_combine(nHash, maLocalSfxItemSet.GetHashCode()); + moHashCode = nHash; +} + bool ScPatternAttr::areSame(const ScPatternAttr* pItem1, const ScPatternAttr* pItem2) { if (pItem1 == pItem2) @@ -1799,6 +1810,7 @@ void ScPatternAttr::InvalidateCaches() mxVisible.reset(); mxNumberFormatKey.reset(); mxLanguageType.reset(); + moHashCode.reset(); } SfxItemSet& ScPatternAttr::GetItemSetWritable() diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx index 5a7efdac8708..ae60b661a8ff 100644 --- a/svl/source/items/itemset.cxx +++ b/svl/source/items/itemset.cxx @@ -27,6 +27,7 @@ #include <libxml/xmlwriter.h> #include <tools/XmlWriter.hxx> +#include <o3tl/hash_combine.hxx> #include <sal/log.hxx> #include <svl/itemset.hxx> @@ -1289,6 +1290,24 @@ bool SfxItemSet::Equals(const SfxItemSet &rCmp, bool bComparePool) const return true; } +size_t SfxItemSet::GetHashCode() const +{ + size_t seed = 0; + + for (PoolItemMap::const_iterator it(m_aPoolItemMap.begin()); it != m_aPoolItemMap.end(); it++) + { + const sal_uInt16 nWhich = it->first; + const SfxPoolItem *pItem = it->second; + + o3tl::hash_combine(seed, nWhich); + if (!IsInvalidItem(pItem) && !IsDisabledItem(pItem) + && pItem && pItem->supportsHashCode()) + o3tl::hash_combine(seed, pItem->hashCode()); + } + + return seed; +} + std::unique_ptr<SfxItemSet> SfxItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const { if (pToPool && pToPool != GetPool()) commit 707fa629bb0ca29d896271e819819ef482fa7102 Author: Noel Grandin <[email protected]> AuthorDate: Wed Dec 31 12:19:31 2025 +0200 Commit: Noel Grandin <[email protected]> CommitDate: Thu Jan 1 09:10:42 2026 +0100 some 'make uicheck' fixes for windows (1) Fix a crash when calling a disposed listbox. (2) Load files on the main thread, prevents deadlocks Change-Id: I24e415bb589ef9cf9e0587725a9213257748ae45 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196354 Reviewed-by: Noel Grandin <[email protected]> Tested-by: Jenkins diff --git a/uitest/uitest/test.py b/uitest/uitest/test.py index 883d6564df8d..98ede61a6cf1 100644 --- a/uitest/uitest/test.py +++ b/uitest/uitest/test.py @@ -86,7 +86,7 @@ class UITest(object): return time.sleep(DEFAULT_SLEEP) - def load_component_from_url(self, url, eventName="OnLoad", load_props=()): + def load_component_from_url(self, url, eventName="OnLoad", load_props=mkPropertyValues({"OnMainThread":True})): with EventListener(self._xContext, eventName) as event: component = self.get_desktop().loadComponentFromURL(url, "_default", 0, load_props) while True: @@ -99,7 +99,7 @@ class UITest(object): # Calls UITest.close_doc at exit @contextmanager - def load_file(self, url, load_props=()): + def load_file(self, url, load_props=mkPropertyValues({"OnMainThread":True})): try: yield self.load_component_from_url(url, "OnLoad", load_props) finally: diff --git a/vcl/source/control/listbox.cxx b/vcl/source/control/listbox.cxx index ce1512b05d67..58b789d4bc56 100644 --- a/vcl/source/control/listbox.cxx +++ b/vcl/source/control/listbox.cxx @@ -569,6 +569,8 @@ void ListBox::setPosSizePixel( tools::Long nX, tools::Long nY, tools::Long nWidt void ListBox::Resize() { + if (isDisposed()) + return; Size aOutSz = GetOutputSizePixel(); if( IsDropDownBox() ) {
