sc/inc/column.hxx | 2 - sc/inc/interpretercontext.hxx | 47 ++++++++++++++++------- sc/inc/patattr.hxx | 2 + sc/source/core/data/patattr.cxx | 11 +++++ sc/source/core/tool/interpretercontext.cxx | 57 ++++++++++++++++++++++++----- 5 files changed, 94 insertions(+), 25 deletions(-)
New commits: commit e310c8714cba16f592d59596caadf39bd01b61d0 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Thu Feb 29 20:09:09 2024 +0000 Commit: Adolfo Jayme Barrientos <fit...@ubuntu.com> CommitDate: Mon Apr 15 05:55:54 2024 +0200 avoid SvNumberFormatter lock in formula-group-threading keep a per-interpret-thread cache of the SvNumberFormatter mapping while formula-group-threading, this is similar to: commit c2d8341ee392949274b901abfd44d9645d2e4e36 Date: Tue Oct 15 08:32:22 2019 +0530 Cache last used number-format-type in interpreter-context Change-Id: Ie99807eaf2f3260cec357f9d66307df0a69826e9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164227 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> (cherry picked from commit 2c3605405225de4b850064cf25b15cd64be1409b) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165748 Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 733923b0f58c..69850197bdaa 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -984,7 +984,7 @@ inline const SfxPoolItem& ScColumnData::GetAttr( SCROW nRow, sal_uInt16 nWhich, inline sal_uInt32 ScColumnData::GetNumberFormat( const ScInterpreterContext& rContext, SCROW nRow ) const { - return pAttrArray->GetPattern( nRow )->GetNumberFormat( rContext.GetFormatTable() ); + return pAttrArray->GetPattern( nRow )->GetNumberFormat( rContext ); } inline void ScColumn::AddCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex ) diff --git a/sc/inc/interpretercontext.hxx b/sc/inc/interpretercontext.hxx index 39d528cb6ca9..11e2c6990c8e 100644 --- a/sc/inc/interpretercontext.hxx +++ b/sc/inc/interpretercontext.hxx @@ -9,8 +9,11 @@ #pragma once +#include <array> #include <vector> #include <memory> +#include <i18nlangtag/lang.h> +#include <svl/numformat.hxx> #include "types.hxx" namespace formula @@ -34,20 +37,6 @@ struct DelayedSetNumberFormat sal_uInt32 mnNumberFormat; }; -struct NFIndexAndFmtType -{ - sal_uInt32 nIndex; - SvNumFormatType eType : 16; - bool bIsValid : 1; - - NFIndexAndFmtType() - : nIndex(0) - , eType(static_cast<SvNumFormatType>(0)) - , bIsValid(false) - { - } -}; - class ScInterpreterContextPool; struct ScInterpreterContext @@ -77,6 +66,8 @@ struct ScInterpreterContext SvNumFormatType GetNumberFormatType(sal_uInt32 nFIndex) const; + sal_uInt32 GetFormatForLanguageIfBuiltIn(sal_uInt32 nFormat, LanguageType eLnge) const; + private: friend class ScInterpreterContextPool; void ResetTokens(); @@ -85,7 +76,33 @@ private: void ClearLookupCache(const ScDocument* pDoc); void initFormatTable(); SvNumberFormatter* mpFormatter; - mutable NFIndexAndFmtType maNFTypeCache; + + // Some temp caches of the 4 most recent results from NumberFormatting + // lookups. + struct NFBuiltIn + { + sal_uInt64 nKey; + sal_uInt32 nFormat; + NFBuiltIn() + : nKey(SAL_MAX_UINT64) + , nFormat(SAL_MAX_UINT32) + { + } + }; + // from format+lang to builtin format + mutable std::array<NFBuiltIn, 4> maNFBuiltInCache; + struct NFType + { + sal_uInt32 nKey; + SvNumFormatType eType; + NFType() + : nKey(SAL_MAX_UINT32) + , eType(SvNumFormatType::ALL) + { + } + }; + // from format index to type + mutable std::array<NFType, 4> maNFTypeCache; }; class ScThreadedInterpreterContextGetterGuard; diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx index d6536551f965..e4b149516c0f 100644 --- a/sc/inc/patattr.hxx +++ b/sc/inc/patattr.hxx @@ -31,6 +31,7 @@ namespace vcl { class Font; } namespace model { class ComplexColor; } +struct ScInterpreterContext; class OutputDevice; class Fraction; class ScStyleSheet; @@ -171,6 +172,7 @@ public: bool IsSymbolFont() const; sal_uInt32 GetNumberFormat( SvNumberFormatter* ) const; + sal_uInt32 GetNumberFormat( const ScInterpreterContext& rContext ) const; sal_uInt32 GetNumberFormat( SvNumberFormatter* pFormatter, const SfxItemSet* pCondSet ) const; diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx index 4bb79828da13..f5db8533cfe0 100644 --- a/sc/source/core/data/patattr.cxx +++ b/sc/source/core/data/patattr.cxx @@ -1412,6 +1412,17 @@ sal_uInt32 ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter ) const return nFormat; } +sal_uInt32 ScPatternAttr::GetNumberFormat( const ScInterpreterContext& rContext ) const +{ + sal_uInt32 nFormat = getNumberFormatKey(GetItemSet()); + LanguageType eLang = getLanguageType(GetItemSet()); + if ( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && eLang == LANGUAGE_SYSTEM ) + ; // it remains as it is + else + nFormat = rContext.GetFormatForLanguageIfBuiltIn( nFormat, eLang ); + return nFormat; +} + // the same if conditional formatting is in play: sal_uInt32 ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter, diff --git a/sc/source/core/tool/interpretercontext.cxx b/sc/source/core/tool/interpretercontext.cxx index deb6f6d0ed5b..235d42d03fd6 100644 --- a/sc/source/core/tool/interpretercontext.cxx +++ b/sc/source/core/tool/interpretercontext.cxx @@ -58,7 +58,14 @@ void ScInterpreterContext::SetDocAndFormatter(const ScDocument& rDoc, SvNumberFo mxScLookupCache.reset(); mpDoc = &rDoc; } - mpFormatter = pFormatter; + if (mpFormatter != pFormatter) + { + mpFormatter = pFormatter; + + // drop cache + std::fill(maNFBuiltInCache.begin(), maNFBuiltInCache.end(), NFBuiltIn()); + std::fill(maNFTypeCache.begin(), maNFTypeCache.end(), NFType()); + } } void ScInterpreterContext::initFormatTable() @@ -87,15 +94,47 @@ SvNumFormatType ScInterpreterContext::GetNumberFormatType(sal_uInt32 nFIndex) co return mpFormatter->GetType(nFIndex); } - if (maNFTypeCache.bIsValid && maNFTypeCache.nIndex == nFIndex) - { - return maNFTypeCache.eType; - } + auto aFind = std::find_if(maNFTypeCache.begin(), maNFTypeCache.end(), + [nFIndex](const NFType& e) { return e.nKey == nFIndex; }); + if (aFind != maNFTypeCache.end()) + return aFind->eType; + + SvNumFormatType eType = mpFormatter->GetType(nFIndex); + + std::move_backward(maNFTypeCache.begin(), + std::next(maNFTypeCache.begin(), maNFTypeCache.size() - 1), + maNFTypeCache.end()); + maNFTypeCache[0].nKey = nFIndex; + maNFTypeCache[0].eType = eType; + + return eType; +} + +sal_uInt32 ScInterpreterContext::GetFormatForLanguageIfBuiltIn(sal_uInt32 nFormat, + LanguageType eLnge) const +{ + if (!mpFormatter) + return nFormat; + + if (!mpDoc->IsThreadedGroupCalcInProgress()) + return mpFormatter->GetFormatForLanguageIfBuiltIn(nFormat, eLnge); + + sal_uInt64 nKey = (static_cast<sal_uInt64>(nFormat) << 32) | eLnge.get(); + + auto aFind = std::find_if(maNFBuiltInCache.begin(), maNFBuiltInCache.end(), + [nKey](const NFBuiltIn& e) { return e.nKey == nKey; }); + if (aFind != maNFBuiltInCache.end()) + return aFind->nFormat; + + nFormat = mpFormatter->GetFormatForLanguageIfBuiltIn(nFormat, eLnge); + + std::move_backward(maNFBuiltInCache.begin(), + std::next(maNFBuiltInCache.begin(), maNFBuiltInCache.size() - 1), + maNFBuiltInCache.end()); + maNFBuiltInCache[0].nKey = nKey; + maNFBuiltInCache[0].nFormat = nFormat; - maNFTypeCache.nIndex = nFIndex; - maNFTypeCache.eType = mpFormatter->GetType(nFIndex); - maNFTypeCache.bIsValid = true; - return maNFTypeCache.eType; + return nFormat; } /* ScInterpreterContextPool */