sw/inc/swcrsr.hxx                |    4 +++-
 sw/source/core/crsr/findattr.cxx |    9 ++++++---
 sw/source/core/crsr/findcoll.cxx |    5 +++--
 sw/source/core/crsr/findtxt.cxx  |   24 +++++++++++++++---------
 sw/source/core/crsr/swcrsr.cxx   |    7 +++++--
 sw/source/core/inc/pamtyp.hxx    |    4 +++-
 6 files changed, 35 insertions(+), 18 deletions(-)

New commits:
commit 1159f58831c69680e9f10767d5358e13b66579dd
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Tue Sep 8 11:51:59 2020 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Wed Sep 9 08:25:01 2020 +0200

    tdf#119286 speed up find/replace
    
    SvxSearchItem is very expensive to construct, so move it outside the
    primary loop.
    This takes the time from 6s to 3s for me.
    
    Change-Id: Ie6491761e69c4f787910d7ecfbd071b7e68efd35
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102231
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sw/inc/swcrsr.hxx b/sw/inc/swcrsr.hxx
index 923928887023..a6e634ac3b55 100644
--- a/sw/inc/swcrsr.hxx
+++ b/sw/inc/swcrsr.hxx
@@ -25,6 +25,7 @@
 
 class SfxItemSet;
 struct SwCursor_SavePos;
+class SvxSearchItem;
 namespace i18nutil {
     struct SearchOptions2;
 }
@@ -37,7 +38,8 @@ const int FIND_NO_RING      = 2;
 
 struct SwFindParas
 {
-    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM&, 
bool) = 0;
+    // @param xSearchItem allocate in parent so we can do so outside the 
calling loop
+    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM&, 
bool, std::unique_ptr<SvxSearchItem>& xSearchItem) = 0;
     virtual bool IsReplaceMode() const = 0;
 
 protected:
diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx
index 40d536de3083..8d1cafd41c64 100644
--- a/sw/source/core/crsr/findattr.cxx
+++ b/sw/source/core/crsr/findattr.cxx
@@ -25,6 +25,7 @@
 #include <unotools/syslocale.hxx>
 #include <hintids.hxx>
 #include <svl/itemiter.hxx>
+#include <svl/srchitem.hxx>
 #include <svl/whiter.hxx>
 #include <editeng/colritem.hxx>
 #include <editeng/fontitem.hxx>
@@ -1253,14 +1254,16 @@ struct SwFindParaAttr : public SwFindParas
 
     virtual ~SwFindParaAttr()   {}
 
-    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, 
bool bInReadOnly) override;
+    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, 
bool bInReadOnly,
+                       std::unique_ptr<SvxSearchItem>& xSearchItem) override;
     virtual bool IsReplaceMode() const override;
 };
 
 }
 
 int SwFindParaAttr::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
-        const SwPaM & rRegion, bool bInReadOnly)
+        const SwPaM & rRegion, bool bInReadOnly,
+        std::unique_ptr<SvxSearchItem>& xSearchItem)
 {
     // replace string (only if text given and search is not parameterized)?
     bool bReplaceText = pSearchOpt && ( !pSearchOpt->replaceString.isEmpty() ||
@@ -1310,7 +1313,7 @@ int SwFindParaAttr::DoFind(SwPaM & rCursor, 
SwMoveFnCollection const & fnMove,
             // TODO: searching for attributes in Outliner text?!
 
             // continue search in correct section (pTextRegion)
-            if (sw::FindTextImpl(aSrchPam, *pSearchOpt, 
false/*bSearchInNotes*/, *pSText, fnMove, *pTextRegion, bInReadOnly, m_pLayout) 
&&
+            if (sw::FindTextImpl(aSrchPam, *pSearchOpt, 
false/*bSearchInNotes*/, *pSText, fnMove, *pTextRegion, bInReadOnly, m_pLayout, 
xSearchItem) &&
                 *aSrchPam.GetMark() != *aSrchPam.GetPoint() )
                 break; // found
             else if( !pSet->Count() )
diff --git a/sw/source/core/crsr/findcoll.cxx b/sw/source/core/crsr/findcoll.cxx
index f80fff2c10ee..8385e0a4cf24 100644
--- a/sw/source/core/crsr/findcoll.cxx
+++ b/sw/source/core/crsr/findcoll.cxx
@@ -41,14 +41,15 @@ struct SwFindParaFormatColl : public SwFindParas
         , m_pLayout(pLayout)
     {}
     virtual ~SwFindParaFormatColl() {}
-    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, 
bool bInReadOnly) override;
+    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, 
bool bInReadOnly, std::unique_ptr<SvxSearchItem>& xSearchItem) override;
     virtual bool IsReplaceMode() const override;
 };
 
 }
 
 int SwFindParaFormatColl::DoFind(SwPaM & rCursor, SwMoveFnCollection const & 
fnMove,
-        const SwPaM & rRegion, bool bInReadOnly)
+        const SwPaM & rRegion, bool bInReadOnly,
+        std::unique_ptr<SvxSearchItem>& /*xSearchItem*/)
 {
     int nRet = FIND_FOUND;
     if( bInReadOnly && pReplColl )
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index b7c4afbf1e47..1e9ecef2c2d2 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -369,11 +369,13 @@ static bool DoSearch(SwPaM & rSearchPam,
 
 namespace sw {
 
+// @param xSearchItem allocate in parent so we can do so outside the calling 
loop
 bool FindTextImpl(SwPaM & rSearchPam,
         const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes,
         utl::TextSearch& rSText,
         SwMoveFnCollection const & fnMove, const SwPaM & rRegion,
-        bool bInReadOnly, SwRootFrame const*const pLayout)
+        bool bInReadOnly, SwRootFrame const*const pLayout,
+        std::unique_ptr<SvxSearchItem>& xSearchItem)
 {
     if( rSearchOpt.searchString.isEmpty() )
         return false;
@@ -395,9 +397,12 @@ bool FindTextImpl(SwPaM & rSearchPam,
                           rSearchOpt.searchString == "$^" );
     const bool bChkParaEnd = bRegSearch && rSearchOpt.searchString == "$";
 
-    SvxSearchItem aSearchItem(SID_SEARCH_ITEM); // this is a very expensive 
operation (calling configmgr etc.)
-    aSearchItem.SetSearchOptions(rSearchOpt);
-    aSearchItem.SetBackward(!bSrchForward);
+    if (!xSearchItem)
+    {
+        xSearchItem.reset(new SvxSearchItem(SID_SEARCH_ITEM)); // this is a 
very expensive operation (calling configmgr etc.)
+        xSearchItem->SetSearchOptions(rSearchOpt);
+        xSearchItem->SetBackward(!bSrchForward);
+    }
 
     // LanguageType eLastLang = 0;
     while (nullptr != (pNode = ::GetNode(*pPam, bFirst, fnMove, bInReadOnly, 
pLayout)))
@@ -525,7 +530,7 @@ bool FindTextImpl(SwPaM & rSearchPam,
 
                 if (pObject)
                 {
-                    sal_uInt16 nResult = 
pSdrView->GetTextEditOutlinerView()->StartSearchAndReplace(aSearchItem);
+                    sal_uInt16 nResult = 
pSdrView->GetTextEditOutlinerView()->StartSearchAndReplace(*xSearchItem);
                     if (!nResult)
                     {
                         // If not found, end the text edit.
@@ -577,7 +582,7 @@ bool FindTextImpl(SwPaM & rSearchPam,
                         aPaM.GetMark()->nNode = rTextNode.GetIndex() + 1;
                     }
                     
aPaM.GetMark()->nContent.Assign(aPaM.GetMark()->nNode.GetNode().GetTextNode(), 
0);
-                    if 
(pNode->GetDoc()->getIDocumentDrawModelAccess().Search(aPaM, aSearchItem) && 
pSdrView)
+                    if 
(pNode->GetDoc()->getIDocumentDrawModelAccess().Search(aPaM, *xSearchItem) && 
pSdrView)
                     {
                         if (SdrObject* pObject = pSdrView->GetTextEditObject())
                         {
@@ -931,7 +936,7 @@ struct SwFindParaText : public SwFindParas
         , m_bReplace( bRepl )
         , m_bSearchInNotes( bSearchInNotes )
     {}
-    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, 
bool bInReadOnly) override;
+    virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, 
bool bInReadOnly, std::unique_ptr<SvxSearchItem>& xSearchItem) override;
     virtual bool IsReplaceMode() const override;
     virtual ~SwFindParaText();
 };
@@ -943,13 +948,14 @@ SwFindParaText::~SwFindParaText()
 }
 
 int SwFindParaText::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
-                          const SwPaM & rRegion, bool bInReadOnly)
+                          const SwPaM & rRegion, bool bInReadOnly,
+                          std::unique_ptr<SvxSearchItem>& xSearchItem)
 {
     if( bInReadOnly && m_bReplace )
         bInReadOnly = false;
 
     const bool bFnd = sw::FindTextImpl(rCursor, m_rSearchOpt, m_bSearchInNotes,
-            m_aSText, fnMove, rRegion, bInReadOnly, m_pLayout);
+            m_aSText, fnMove, rRegion, bInReadOnly, m_pLayout, xSearchItem);
 
     if( bFnd && m_bReplace ) // replace string
     {
diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index a4b1d6a54c50..97e46bd827e9 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -23,6 +23,7 @@
 #include <com/sun/star/i18n/XBreakIterator.hpp>
 #include <unotools/charclass.hxx>
 #include <svl/ctloptions.hxx>
+#include <svl/srchitem.hxx>
 #include <swmodule.hxx>
 #include <fmtcntnt.hxx>
 #include <swtblfmt.hxx>
@@ -768,6 +769,7 @@ static sal_uLong lcl_FindSelection( SwFindParas& rParas, 
SwCursor* pCurrentCurso
     sal_uLong nFound = 0;
     const bool bSrchBkwrd = &fnMove == &fnMoveBackward;
     SwPaM *pTmpCursor = pCurrentCursor, *pSaveCursor = pCurrentCursor;
+    std::unique_ptr<SvxSearchItem> xSearchItem;
 
     // only create progress bar for ShellCursor
     bool bIsUnoCursor = dynamic_cast<SwUnoCursor*>(pCurrentCursor) !=  nullptr;
@@ -801,7 +803,7 @@ static sal_uLong lcl_FindSelection( SwFindParas& rParas, 
SwCursor* pCurrentCurso
         // as long as found and not at same position
         while(  *pSttPos <= *pEndPos )
         {
-            nFndRet = rParas.DoFind(*pCurrentCursor, fnMove, aRegion, 
bInReadOnly);
+            nFndRet = rParas.DoFind(*pCurrentCursor, fnMove, aRegion, 
bInReadOnly, xSearchItem);
             if( 0 == nFndRet ||
                 ( pFndRing &&
                   *pFndRing->GetPoint() == *pCurrentCursor->GetPoint() &&
@@ -961,6 +963,7 @@ sal_uLong SwCursor::FindAll( SwFindParas& rParas,
     sal_uLong nFound = 0;
     const bool bMvBkwrd = &fnMove == &fnMoveBackward;
     bool bInReadOnly = IsReadOnlyAvailable();
+    std::unique_ptr<SvxSearchItem> xSearchItem;
 
     SwCursor* pFndRing = nullptr;
     SwNodes& rNds = GetDoc()->GetNodes();
@@ -1089,7 +1092,7 @@ sal_uLong SwCursor::FindAll( SwFindParas& rParas,
         SwPosition aMarkPos( *GetMark() );
         const bool bMarkPos = HasMark() && (eFndRngs == FindRanges::InBody);
 
-        nFound = rParas.DoFind(*this, fnMove, aRegion, bInReadOnly) ? 1 : 0;
+        nFound = rParas.DoFind(*this, fnMove, aRegion, bInReadOnly, 
xSearchItem) ? 1 : 0;
         if (0 != nFound && bMarkPos)
             *GetMark() = aMarkPos;
     }
diff --git a/sw/source/core/inc/pamtyp.hxx b/sw/source/core/inc/pamtyp.hxx
index 9326b348dcc2..b1bb6c1f4722 100644
--- a/sw/source/core/inc/pamtyp.hxx
+++ b/sw/source/core/inc/pamtyp.hxx
@@ -36,6 +36,7 @@ class SwNode;
 class SwNodeIndex;
 class SwContentNode;
 class SwIndex;
+class SvxSearchItem;
 
 namespace i18nutil {
     struct SearchOptions2;
@@ -94,7 +95,8 @@ namespace sw {
                 utl::TextSearch& rSText,
                 SwMoveFnCollection const & fnMove,
                 const SwPaM & rRegion, bool bInReadOnly,
-                SwRootFrame const* pLayout);
+                SwRootFrame const* pLayout,
+                std::unique_ptr<SvxSearchItem>& xSearchItem);
     bool FindFormatImpl(SwPaM & rSearchPam,
                 const SwFormat& rFormat,
                 SwMoveFnCollection const & fnMove,
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to