sw/inc/IDocumentMarkAccess.hxx     |    6 ++++++
 sw/source/core/doc/docbm.cxx       |   10 ++++++++++
 sw/source/core/doc/docredln.cxx    |    8 +++++---
 sw/source/core/inc/MarkManager.hxx |    1 +
 4 files changed, 22 insertions(+), 3 deletions(-)

New commits:
commit b160db48a583bf3657e988f5b6fc7366954fb8da
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Aug 9 19:54:00 2024 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Fri Aug 9 21:44:00 2024 +0200

    speedup lcl_storeAnnotationMarks
    
    we can binary search for the starting point, and we can exit the loop
    early
    
    Change-Id: Ia1ec208f097d3a20c4188968987be87129d4b659
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171707
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index cb64b71e6ac6..e7c98e7a18c2 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -314,6 +314,12 @@ class IDocumentMarkAccess
             const OUString& rProposedName,
             ::sw::mark::InsertMode eMode,
             SwPosition const* pSepPos = nullptr) = 0;
+        /** Find the first AnnotationMark that does not start before.
+
+            @returns
+            an iterator pointing to the mark, or pointing to 
getAnnotationMarksEnd() if nothing was found.
+        */
+        virtual std::vector<sw::mark::AnnotationMark*>::const_iterator 
findFirstAnnotationMarkNotStartsBefore(const SwPosition& rPos) const =0;
         virtual std::vector<sw::mark::Bookmark*>::const_iterator 
findAnnotationBookmark( const OUString& rName ) const = 0;
         virtual void restoreAnnotationMarks(bool bDelete = true) = 0;
         /** Finds the first mark that is starting after.
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index a3e45c5ad70c..500c81fa0be6 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -1706,6 +1706,16 @@ namespace sw::mark
         return static_cast<sw::mark::Bookmark*>(makeMark( rPaM, 
sAnnotationBookmarkName, MarkType::BOOKMARK, eMode, pSepPos));
     }
 
+    // find the first AnnotationMark that does not start before
+    std::vector<sw::mark::AnnotationMark*>::const_iterator 
MarkManager::findFirstAnnotationMarkNotStartsBefore(const SwPosition& rPos) 
const
+    {
+        return std::lower_bound(
+                m_vAnnotationMarks.begin(),
+                m_vAnnotationMarks.end(),
+                rPos,
+                CompareIMarkStartsBefore<AnnotationMark>());
+    }
+
     // find helper bookmark of annotations on tracked deletions
     std::vector<sw::mark::Bookmark*>::const_iterator 
MarkManager::findAnnotationBookmark(const OUString& rName) const
     {
diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index 489c12305b2f..53c833bf915d 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -1790,10 +1790,13 @@ static void lcl_storeAnnotationMarks(SwDoc& rDoc, const 
SwPosition* pStt, const
     // tdf#115815 keep original start position of collapsed annotation ranges
     // as temporary bookmarks (removed after file saving and file loading)
     IDocumentMarkAccess& rDMA(*rDoc.getIDocumentMarkAccess());
-    for (auto iter = rDMA.getAnnotationMarksBegin();
-          iter != rDMA.getAnnotationMarksEnd(); )
+    for (auto iter = rDMA.findFirstAnnotationMarkNotStartsBefore(*pStt);
+          iter != rDMA.getAnnotationMarksEnd(); ++iter)
     {
         SwPosition const& rStartPos((**iter).GetMarkStart());
+        // vector is sorted by start pos, so we can exit early
+        if ( rStartPos > *pEnd )
+            break;
         if ( *pStt <= rStartPos && rStartPos < *pEnd )
         {
             auto pOldMark = rDMA.findAnnotationBookmark((**iter).GetName());
@@ -1815,7 +1818,6 @@ static void lcl_storeAnnotationMarks(SwDoc& rDoc, const 
SwPosition* pStt, const
                 }
             }
         }
-        ++iter;
     }
 }
 
diff --git a/sw/source/core/inc/MarkManager.hxx 
b/sw/source/core/inc/MarkManager.hxx
index 4c7be744e48b..0b2d8850a201 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -131,6 +131,7 @@ namespace sw::mark {
                 const OUString& rName,
                 sw::mark::InsertMode eMode,
                 SwPosition const* pSepPos = nullptr) override;
+            virtual std::vector<sw::mark::AnnotationMark*>::const_iterator 
findFirstAnnotationMarkNotStartsBefore(const SwPosition& rPos) const override;
             virtual std::vector<sw::mark::Bookmark*>::const_iterator 
findAnnotationBookmark( const OUString& rName ) const override;
             virtual void restoreAnnotationMarks(bool bDelete = true) override;
 

Reply via email to