include/unotools/charclass.hxx | 4 - linguistic/source/misc.cxx | 22 +----- linguistic/source/spelldsp.cxx | 6 - svl/source/numbers/zforlist.cxx | 2 sw/inc/calc.hxx | 3 sw/source/core/bastyp/calc.cxx | 7 + sw/source/core/fields/usrfld.cxx | 6 - sw/source/core/txtnode/txtedt.cxx | 11 +-- unotools/source/i18n/charclass.cxx | 133 ++++++------------------------------- unotools/source/misc/syslocale.cxx | 12 +-- xmloff/source/style/xmlnumfe.cxx | 2 11 files changed, 56 insertions(+), 152 deletions(-)
New commits: commit dac29c278531d5474289eb54aa03987c4958ac83 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Thu Sep 16 11:03:04 2021 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri Sep 17 10:49:21 2021 +0200 speedup toUpperCase when called in parallel by removing locking from CharClass, which means we need to make it an immutable class Since SharedStringPool in sc/ stores a pointer to the CharClass in use, we have to tweak SvtSysLocale so that the object does not change location. Change-Id: I2c62d354fa542ebc04e755ce5b9b9e2ddff76a64 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122185 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/include/unotools/charclass.hxx b/include/unotools/charclass.hxx index 521f3abe003b..f3c81a18e51b 100644 --- a/include/unotools/charclass.hxx +++ b/include/unotools/charclass.hxx @@ -62,7 +62,6 @@ class UNOTOOLS_DLLPUBLIC CharClass { LanguageTag maLanguageTag; css::uno::Reference< css::i18n::XCharacterClassification > xCC; - mutable std::mutex aMutex; CharClass(const CharClass&) = delete; CharClass& operator=(const CharClass&) = delete; @@ -79,9 +78,6 @@ public: ~CharClass(); - /// set a new Locale - void setLanguageTag( const LanguageTag& rLanguageTag ); - /// get current Locale const LanguageTag& getLanguageTag() const; diff --git a/linguistic/source/misc.cxx b/linguistic/source/misc.cxx index 363b5f445a47..f541b97551e6 100644 --- a/linguistic/source/misc.cxx +++ b/linguistic/source/misc.cxx @@ -566,21 +566,10 @@ uno::Reference< XHyphenatedWord > RebuildHyphensAndControlChars( return xRes; } -static CharClass & lcl_GetCharClass() -{ - static CharClass aCC( LanguageTag( LANGUAGE_ENGLISH_US )); - return aCC; -} - -static std::mutex s_GetCharClassMutex; - bool IsUpper( const OUString &rText, sal_Int32 nPos, sal_Int32 nLen, LanguageType nLanguage ) { - std::scoped_lock aGuard( s_GetCharClassMutex ); - - CharClass &rCC = lcl_GetCharClass(); - rCC.setLanguageTag( LanguageTag( nLanguage )); - sal_Int32 nFlags = rCC.getStringType( rText, nPos, nLen ); + CharClass aCC(( LanguageTag( nLanguage ) )); + sal_Int32 nFlags = aCC.getStringType( rText, nPos, nLen ); return (nFlags & KCharacterType::UPPER) && !(nFlags & KCharacterType::LOWER); } @@ -612,11 +601,8 @@ CapType capitalType(const OUString& aTerm, CharClass const * pCC) OUString ToLower( const OUString &rText, LanguageType nLanguage ) { - std::scoped_lock aGuard( s_GetCharClassMutex ); - - CharClass &rCC = lcl_GetCharClass(); - rCC.setLanguageTag( LanguageTag( nLanguage )); - return rCC.lowercase( rText ); + CharClass aCC(( LanguageTag( nLanguage ) )); + return aCC.lowercase( rText ); } // sorted(!) array of unicode ranges for code points that are exclusively(!) used as numbers diff --git a/linguistic/source/spelldsp.cxx b/linguistic/source/spelldsp.cxx index dbece3def648..c1b309b00adf 100644 --- a/linguistic/source/spelldsp.cxx +++ b/linguistic/source/spelldsp.cxx @@ -813,9 +813,9 @@ void SpellCheckerDispatcher::FlushSpellCache() void SpellCheckerDispatcher::setCharClass(const LanguageTag& rLanguageTag) { - if (!m_pCharClass) - m_pCharClass.reset( new CharClass(rLanguageTag) ); - m_pCharClass->setLanguageTag(rLanguageTag); + if (m_pCharClass && m_pCharClass->getLanguageTag() == rLanguageTag) + return; + m_pCharClass.reset( new CharClass(rLanguageTag) ); } diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx index 6ef3dddcd016..077d04867e0f 100644 --- a/svl/source/numbers/zforlist.cxx +++ b/svl/source/numbers/zforlist.cxx @@ -338,7 +338,7 @@ void SvNumberFormatter::ChangeIntl(LanguageType eLnge) ActLnge = eLnge; maLanguageTag.reset( eLnge ); - pCharClass->setLanguageTag( maLanguageTag ); + pCharClass.reset( new CharClass( m_xContext, maLanguageTag ) ); xLocaleData.changeLocale( maLanguageTag ); xCalendar.changeLocale( maLanguageTag.getLocale() ); xTransliteration.changeLocale( eLnge ); diff --git a/sw/inc/calc.hxx b/sw/inc/calc.hxx index 4121cc7f0e72..5ff42c15c59e 100644 --- a/sw/inc/calc.hxx +++ b/sw/inc/calc.hxx @@ -240,7 +240,8 @@ public: bool Push(const SwUserFieldType* pUserFieldType); void Pop(); - CharClass* GetCharClass(); + const CharClass* GetCharClass() const; + void SetCharClass(const LanguageTag& rLanguageTag); void SetCalcError( SwCalcError eErr ) { m_eError = eErr; } bool IsCalcError() const { return SwCalcError::NONE != m_eError && SwCalcError::NaN != m_eError; } diff --git a/sw/source/core/bastyp/calc.cxx b/sw/source/core/bastyp/calc.cxx index d5b2968dce43..4840e81497b2 100644 --- a/sw/source/core/bastyp/calc.cxx +++ b/sw/source/core/bastyp/calc.cxx @@ -622,11 +622,16 @@ void SwCalc::Pop() m_aRekurStack.pop_back(); } -CharClass* SwCalc::GetCharClass() +const CharClass* SwCalc::GetCharClass() const { return m_pCharClass; } +void SwCalc::SetCharClass(const LanguageTag& rLanguageTag) +{ + m_pCharClass = new CharClass( ::comphelper::getProcessComponentContext(), rLanguageTag ); +} + SwCalcOper SwCalc::GetToken() { if( m_nCommandPos >= m_sCommand.getLength() ) diff --git a/sw/source/core/fields/usrfld.cxx b/sw/source/core/fields/usrfld.cxx index d9ff1ff6311f..9dcf373edbfd 100644 --- a/sw/source/core/fields/usrfld.cxx +++ b/sw/source/core/fields/usrfld.cxx @@ -246,7 +246,7 @@ double SwUserFieldType::GetValue( SwCalc& rCalc ) // See if we need to temporarily switch rCalc's language: in case it // differs from the field type locale. - CharClass* pCharClass = rCalc.GetCharClass(); + const CharClass* pCharClass = rCalc.GetCharClass(); LanguageTag aCharClassLanguage = pCharClass->getLanguageTag(); LanguageTag aContentLang(m_aContentLang); @@ -256,14 +256,14 @@ double SwUserFieldType::GetValue( SwCalc& rCalc ) bool bSwitchLanguage = m_aContentLang != aCharClassLanguage.getBcp47(); if (bSwitchLanguage) - pCharClass->setLanguageTag(aContentLang); + rCalc.SetCharClass(aContentLang); m_nValue = rCalc.Calculate( m_aContent ).GetDouble(); // we than have to set the proper char class languageTag again if (bSwitchLanguage) - pCharClass->setLanguageTag(aCharClassLanguage); + rCalc.SetCharClass(aCharClassLanguage); rCalc.Pop(); diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx index 725d522b7208..943c09148155 100644 --- a/sw/source/core/txtnode/txtedt.cxx +++ b/sw/source/core/txtnode/txtedt.cxx @@ -810,8 +810,8 @@ bool SwScanner::NextWord() m_nBegin = m_nBegin + m_nLength; Boundary aBound; - CharClass& rCC = GetAppCharClass(); - LanguageTag aOldLanguageTag = rCC.getLanguageTag(); + const CharClass* pCC = &GetAppCharClass(); + std::optional<CharClass> xLocalCharClass; while ( true ) { @@ -830,8 +830,9 @@ bool SwScanner::NextWord() if ( m_nWordType != i18n::WordType::WORD_COUNT ) { - rCC.setLanguageTag( LanguageTag( g_pBreakIt->GetLocale( m_aCurrentLang )) ); - if ( rCC.isLetterNumeric(OUString(m_aText[m_nBegin])) ) + xLocalCharClass.emplace(LanguageTag( g_pBreakIt->GetLocale( m_aCurrentLang ) )); + pCC = &*xLocalCharClass; + if ( pCC->isLetterNumeric(OUString(m_aText[m_nBegin])) ) break; } else @@ -866,8 +867,6 @@ bool SwScanner::NextWord() break; } // end while( true ) - rCC.setLanguageTag( aOldLanguageTag ); - // #i89042, as discussed with HDU: don't evaluate script changes for word count. Use whole word. if ( m_nWordType == i18n::WordType::WORD_COUNT ) { diff --git a/unotools/source/i18n/charclass.cxx b/unotools/source/i18n/charclass.cxx index c326e4315681..dee05388e150 100644 --- a/unotools/source/i18n/charclass.cxx +++ b/unotools/source/i18n/charclass.cxx @@ -33,16 +33,13 @@ CharClass::CharClass( const Reference< uno::XComponentContext > & rxContext, const LanguageTag& rLanguageTag ) - : - maLanguageTag( rLanguageTag) + : maLanguageTag( rLanguageTag) { xCC = CharacterClassification::create( rxContext ); } -CharClass::CharClass( - const LanguageTag& rLanguageTag ) - : - maLanguageTag( rLanguageTag) +CharClass::CharClass( const LanguageTag& rLanguageTag ) + : maLanguageTag( rLanguageTag) { xCC = CharacterClassification::create( comphelper::getProcessComponentContext() ); } @@ -51,21 +48,13 @@ CharClass::~CharClass() { } -void CharClass::setLanguageTag( const LanguageTag& rLanguageTag ) -{ - std::scoped_lock aGuard( aMutex ); - maLanguageTag = rLanguageTag; -} - const LanguageTag& CharClass::getLanguageTag() const { - std::scoped_lock aGuard( aMutex ); return maLanguageTag; } const css::lang::Locale& CharClass::getMyLocale() const { - // Mutex locked by callers. return maLanguageTag.getLocale(); } @@ -113,12 +102,8 @@ bool CharClass::isAlpha( const OUString& rStr, sal_Int32 nPos ) const try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & - nCharClassAlphaType) != 0; - } + return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & + nCharClassAlphaType) != 0; } catch ( const Exception& ) { @@ -135,12 +120,8 @@ bool CharClass::isLetter( const OUString& rStr, sal_Int32 nPos ) const try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & - nCharClassLetterType) != 0; - } + return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & + nCharClassLetterType) != 0; } catch ( const Exception& ) { @@ -153,11 +134,7 @@ bool CharClass::isLetter( const OUString& rStr ) const { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return isLetterType( xCC->getStringType( rStr, 0, rStr.getLength(), getMyLocale() ) ); - } + return isLetterType( xCC->getStringType( rStr, 0, rStr.getLength(), getMyLocale() ) ); } catch ( const Exception& ) { @@ -174,12 +151,8 @@ bool CharClass::isDigit( const OUString& rStr, sal_Int32 nPos ) const try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & - KCharacterType::DIGIT) != 0; - } + return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & + KCharacterType::DIGIT) != 0; } catch ( const Exception& ) { @@ -192,11 +165,7 @@ bool CharClass::isNumeric( const OUString& rStr ) const { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return isNumericType( xCC->getStringType( rStr, 0, rStr.getLength(), getMyLocale() ) ); - } + return isNumericType( xCC->getStringType( rStr, 0, rStr.getLength(), getMyLocale() ) ); } catch ( const Exception& ) { @@ -213,12 +182,8 @@ bool CharClass::isAlphaNumeric( const OUString& rStr, sal_Int32 nPos ) const try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & + return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & (nCharClassAlphaType | KCharacterType::DIGIT)) != 0; - } } catch ( const Exception& ) { @@ -235,12 +200,8 @@ bool CharClass::isLetterNumeric( const OUString& rStr, sal_Int32 nPos ) const try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & - (nCharClassLetterType | KCharacterType::DIGIT)) != 0; - } + return (xCC->getCharacterType( rStr, nPos, getMyLocale() ) & + (nCharClassLetterType | KCharacterType::DIGIT)) != 0; } catch ( const Exception& ) { @@ -253,11 +214,7 @@ bool CharClass::isLetterNumeric( const OUString& rStr ) const { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return isLetterNumericType( xCC->getStringType( rStr, 0, rStr.getLength(), getMyLocale() ) ); - } + return isLetterNumericType( xCC->getStringType( rStr, 0, rStr.getLength(), getMyLocale() ) ); } catch ( const Exception& ) { @@ -270,11 +227,7 @@ OUString CharClass::titlecase(const OUString& rStr, sal_Int32 nPos, sal_Int32 nC { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return xCC->toTitle( rStr, nPos, nCount, getMyLocale() ); - } + return xCC->toTitle( rStr, nPos, nCount, getMyLocale() ); } catch ( const Exception& ) { @@ -287,11 +240,7 @@ OUString CharClass::uppercase( const OUString& rStr, sal_Int32 nPos, sal_Int32 n { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return xCC->toUpper( rStr, nPos, nCount, getMyLocale() ); - } + return xCC->toUpper( rStr, nPos, nCount, getMyLocale() ); } catch ( const Exception& ) { @@ -304,11 +253,7 @@ OUString CharClass::lowercase( const OUString& rStr, sal_Int32 nPos, sal_Int32 n { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return xCC->toLower( rStr, nPos, nCount, getMyLocale() ); - } + return xCC->toLower( rStr, nPos, nCount, getMyLocale() ); } catch ( const Exception& ) { @@ -321,11 +266,7 @@ sal_Int16 CharClass::getType( const OUString& rStr, sal_Int32 nPos ) const { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return xCC->getType( rStr, nPos ); - } + return xCC->getType( rStr, nPos ); } catch ( const Exception& ) { @@ -338,11 +279,7 @@ css::i18n::DirectionProperty CharClass::getCharacterDirection( const OUString& r { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return static_cast<css::i18n::DirectionProperty>(xCC->getCharacterDirection( rStr, nPos )); - } + return static_cast<css::i18n::DirectionProperty>(xCC->getCharacterDirection( rStr, nPos )); } catch ( const Exception& ) { @@ -355,11 +292,7 @@ css::i18n::UnicodeScript CharClass::getScript( const OUString& rStr, sal_Int32 n { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return static_cast<css::i18n::UnicodeScript>(xCC->getScript( rStr, nPos )); - } + return static_cast<css::i18n::UnicodeScript>(xCC->getScript( rStr, nPos )); } catch ( const Exception& ) { @@ -372,11 +305,7 @@ sal_Int32 CharClass::getCharacterType( const OUString& rStr, sal_Int32 nPos ) co { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return xCC->getCharacterType( rStr, nPos, getMyLocale() ); - } + return xCC->getCharacterType( rStr, nPos, getMyLocale() ); } catch ( const Exception& ) { @@ -389,11 +318,7 @@ sal_Int32 CharClass::getStringType( const OUString& rStr, sal_Int32 nPos, sal_In { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return xCC->getStringType( rStr, nPos, nCount, getMyLocale() ); - } + return xCC->getStringType( rStr, nPos, nCount, getMyLocale() ); } catch ( const Exception& ) { @@ -412,13 +337,9 @@ css::i18n::ParseResult CharClass::parseAnyToken( { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return xCC->parseAnyToken( rStr, nPos, getMyLocale(), + return xCC->parseAnyToken( rStr, nPos, getMyLocale(), nStartCharFlags, userDefinedCharactersStart, nContCharFlags, userDefinedCharactersCont ); - } } catch ( const Exception& ) { @@ -438,13 +359,9 @@ css::i18n::ParseResult CharClass::parsePredefinedToken( { try { - if ( xCC.is() ) - { - std::scoped_lock aGuard( aMutex ); - return xCC->parsePredefinedToken( nTokenType, rStr, nPos, getMyLocale(), + return xCC->parsePredefinedToken( nTokenType, rStr, nPos, getMyLocale(), nStartCharFlags, userDefinedCharactersStart, nContCharFlags, userDefinedCharactersCont ); - } } catch ( const Exception& ) { diff --git a/unotools/source/misc/syslocale.cxx b/unotools/source/misc/syslocale.cxx index 2882eb7fc436..b55e1316cabe 100644 --- a/unotools/source/misc/syslocale.cxx +++ b/unotools/source/misc/syslocale.cxx @@ -47,8 +47,8 @@ class SvtSysLocale_Impl : public utl::ConfigurationListener { public: SvtSysLocaleOptions aSysLocaleOptions; - std::unique_ptr<LocaleDataWrapper> pLocaleData; - std::unique_ptr<CharClass> pCharClass; + std::unique_ptr<LocaleDataWrapper> pLocaleData; + std::optional<CharClass> moCharClass; SvtSysLocale_Impl(); virtual ~SvtSysLocale_Impl() override; @@ -77,9 +77,9 @@ SvtSysLocale_Impl::~SvtSysLocale_Impl() CharClass& SvtSysLocale_Impl::GetCharClass() { - if ( !pCharClass ) - pCharClass.reset(new CharClass( aSysLocaleOptions.GetRealLanguageTag() )); - return *pCharClass; + if ( !moCharClass ) + moCharClass.emplace( aSysLocaleOptions.GetRealLanguageTag() ); + return *moCharClass; } void SvtSysLocale_Impl::ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints nHint ) @@ -93,7 +93,7 @@ void SvtSysLocale_Impl::ConfigurationChanged( utl::ConfigurationBroadcaster*, Co const LanguageTag& rLanguageTag = aSysLocaleOptions.GetRealLanguageTag(); if ( nHint & ConfigurationHints::Locale ) { - GetCharClass().setLanguageTag( rLanguageTag ); + moCharClass.emplace( rLanguageTag ); } pLocaleData.reset(new LocaleDataWrapper(rLanguageTag, getDateAcceptancePatternsConfig())); } diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx index 990cf15461a7..42a918df4573 100644 --- a/xmloff/source/style/xmlnumfe.cxx +++ b/xmloff/source/style/xmlnumfe.cxx @@ -895,7 +895,7 @@ bool SvXMLNumFmtExport::WriteTextWithCurrency_Impl( const OUString& rString, OUString sCurString, sDummy; pFormatter->GetCompatibilityCurrency( sCurString, sDummy ); - pCharClass->setLanguageTag( aLanguageTag ); + pCharClass.reset( new CharClass( pFormatter->GetComponentContext(), aLanguageTag ) ); OUString sUpperStr = pCharClass->uppercase(rString); sal_Int32 nPos = lcl_FindSymbol( sUpperStr, sCurString ); if ( nPos >= 0 )