From b160db48a583bf3657e988f5b6fc7366954fb8da Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Fri, 9 Aug 2024 19:54:00 +0200 Subject: 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 --- 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(-) (limited to 'sw') 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::const_iterator findFirstAnnotationMarkNotStartsBefore(const SwPosition& rPos) const =0; virtual std::vector::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(makeMark( rPaM, sAnnotationBookmarkName, MarkType::BOOKMARK, eMode, pSepPos)); } + // find the first AnnotationMark that does not start before + std::vector::const_iterator MarkManager::findFirstAnnotationMarkNotStartsBefore(const SwPosition& rPos) const + { + return std::lower_bound( + m_vAnnotationMarks.begin(), + m_vAnnotationMarks.end(), + rPos, + CompareIMarkStartsBefore()); + } + // find helper bookmark of annotations on tracked deletions std::vector::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::const_iterator findFirstAnnotationMarkNotStartsBefore(const SwPosition& rPos) const override; virtual std::vector::const_iterator findAnnotationBookmark( const OUString& rName ) const override; virtual void restoreAnnotationMarks(bool bDelete = true) override; -- cgit