[Libreoffice-commits] core.git: include/unotools linguistic/source svl/source sw/inc sw/source unotools/source xmloff/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Fri Sep 17 08:49:55 UTC 2021


 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.grandin at collabora.co.uk>
AuthorDate: Thu Sep 16 11:03:04 2021 +0200
Commit:     Noel Grandin <noel.grandin at 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.grandin at 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 )


More information about the Libreoffice-commits mailing list