sc/inc/patattr.hxx | 4 ++++ sc/source/core/data/global.cxx | 6 ++++++ sc/source/core/data/patattr.cxx | 16 ++++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-)
New commits: commit 6adabd915d931b845fcf2fef15fbf3fca14ec9b3 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Sun Mar 6 16:53:47 2022 +0100 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Mon Mar 7 10:40:46 2022 +0100 faster check whether attributes have changed (tdf#117366) If the two item sets are equal, then trivially nothing has changed between them. Change-Id: Ib4c5922959603a0a28e11967a17ba4607e6a010f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131080 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx index 4570924d5d17..5b031f488467 100644 --- a/sc/inc/patattr.hxx +++ b/sc/inc/patattr.hxx @@ -19,6 +19,8 @@ #pragma once +#include <optional> + #include <svl/setitem.hxx> #include <svl/itemset.hxx> #include <svl/languageoptions.hxx> @@ -145,6 +147,8 @@ public: void SetKey(sal_uInt64 nKey); sal_uInt64 GetKey() const; + static std::optional<bool> FastEqualPatternSets( const SfxItemSet& rSet1, const SfxItemSet& rSet2 ); + // TODO: tdf#135215: This is a band-aid to detect changes and invalidate the hash, // a proper way would be probably to override SfxItemSet::Changed(), but 6cb400f41df0dd10 // hardcoded SfxSetItem to contain SfxItemSet. diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx index 0c52427539c0..60a347bd236f 100644 --- a/sc/source/core/data/global.cxx +++ b/sc/source/core/data/global.cxx @@ -182,6 +182,12 @@ bool ScGlobal::CheckWidthInvalidate( bool& bNumFormatChanged, const SfxItemSet& rNewAttrs, const SfxItemSet& rOldAttrs ) { + std::optional<bool> equal = ScPatternAttr::FastEqualPatternSets( rNewAttrs, rOldAttrs ); + if( equal.has_value() && equal ) + { + bNumFormatChanged = false; + return false; + } // Check whether attribute changes in rNewAttrs compared to rOldAttrs render // the text width at a cell invalid bNumFormatChanged = diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx index 7e5d3b73f51c..a0077be5696a 100644 --- a/sc/source/core/data/patattr.cxx +++ b/sc/source/core/data/patattr.cxx @@ -119,24 +119,32 @@ static bool StrCmp( const OUString* pStr1, const OUString* pStr2 ) constexpr size_t compareSize = ATTR_PATTERN_END - ATTR_PATTERN_START + 1; -static bool EqualPatternSets( const SfxItemSet& rSet1, const SfxItemSet& rSet2 ) +std::optional<bool> ScPatternAttr::FastEqualPatternSets( const SfxItemSet& rSet1, const SfxItemSet& rSet2 ) { // #i62090# The SfxItemSet in the SfxSetItem base class always has the same ranges // (single range from ATTR_PATTERN_START to ATTR_PATTERN_END), and the items are pooled, // so it's enough to compare just the pointers (Count just because it's even faster). if ( rSet1.Count() != rSet2.Count() ) - return false; + return { false }; // Actually test_tdf133629 from UITest_calc_tests9 somehow manages to have // a different range (and I don't understand enough why), so better be safe and compare fully. if( rSet1.TotalCount() != compareSize || rSet2.TotalCount() != compareSize ) - return rSet1 == rSet2; + return std::nullopt; SfxPoolItem const ** pItems1 = rSet1.GetItems_Impl(); // inline method of SfxItemSet SfxPoolItem const ** pItems2 = rSet2.GetItems_Impl(); - return ( 0 == memcmp( pItems1, pItems2, compareSize * sizeof(pItems1[0]) ) ); + return { memcmp( pItems1, pItems2, compareSize * sizeof(pItems1[0]) ) == 0 }; +} + +static bool EqualPatternSets( const SfxItemSet& rSet1, const SfxItemSet& rSet2 ) +{ + std::optional<bool> equal = ScPatternAttr::FastEqualPatternSets( rSet1, rSet2 ); + if(equal.has_value()) + return *equal; + return rSet1 == rSet2; } bool ScPatternAttr::operator==( const SfxPoolItem& rCmp ) const