include/svx/svdmodel.hxx             |    8 +++---
 sd/source/filter/pdf/sdpdffilter.cxx |    4 ++-
 svx/source/svdraw/svdmodel.cxx       |   46 ++++++++++++++++++-----------------
 3 files changed, 31 insertions(+), 27 deletions(-)

New commits:
commit e4251f16e8659b02d36a9b44215970e77a67ead5
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Sep 6 12:55:26 2024 +0200
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Fri Sep 13 11:20:41 2024 +0200

    reduce time spent in RecalcPageNums when importing PDF
    
    when we have lots of pages, we trigger a O(n^2) loop.
    
    Do two things to reduce this
    (a) be smarter about recalculating page numbers, so we only recalculate
    the set of page numbers that need recalculating
    (b) duplicate the last page repeatedly, instead of the first page, so we
    don't recalculate all the page numbers for each page we duplicate
    
    Change-Id: I40aca812b47a9551039c5855b1c8d26f5f171f41
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172950
    Reviewed-by: Michael Meeks <michael.me...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index 68565e264bc3..f037baf6fcc4 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -199,12 +199,12 @@ protected:
     std::deque<std::unique_ptr<SfxUndoAction>> m_aRedoStack;
     std::unique_ptr<SdrUndoGroup> m_pCurrentUndoGroup;  // For multi-level
     sal_uInt16          m_nUndoLevel;                   // undo nesting
+    sal_uInt16          m_nPageNumsDirtyFrom = SAL_MAX_UINT16;
+    sal_uInt16          m_nMasterPageNumsDirtyFrom = SAL_MAX_UINT16;
     bool                m_bIsWriter:1;        // to clean up pMyPool from 303a
     bool                m_bThemedControls:1;  // If false UnoControls should 
not use theme colors
     bool                mbUndoEnabled:1;  // If false no undo is recorded or 
we are during the execution of an undo action
     bool                mbChanged:1;
-    bool                m_bPagNumsDirty:1;
-    bool                m_bMPgNumsDirty:1;
     bool                m_bTransportContainer:1;  // doc is temporary object 
container, no display (e.g. clipboard)
     bool                m_bReadOnly:1;
     bool                m_bTransparentTextFrames:1;
@@ -397,8 +397,8 @@ public:
     static OUString  GetPercentString(const Fraction& rVal);
 
     // RecalcPageNums is ordinarily only called by the Page.
-    bool             IsPagNumsDirty() const                     { return 
m_bPagNumsDirty; };
-    bool             IsMPgNumsDirty() const                     { return 
m_bMPgNumsDirty; };
+    bool             IsPagNumsDirty() const                     { return 
m_nPageNumsDirtyFrom != SAL_MAX_UINT16; }
+    bool             IsMPgNumsDirty() const                     { return 
m_nMasterPageNumsDirtyFrom != SAL_MAX_UINT16; }
     void             RecalcPageNums(bool bMaster);
     // After the Insert the Page belongs to the SdrModel.
     virtual void     InsertPage(SdrPage* pPage, sal_uInt16 nPos=0xFFFF);
diff --git a/sd/source/filter/pdf/sdpdffilter.cxx 
b/sd/source/filter/pdf/sdpdffilter.cxx
index 22229e6597ce..068aca1fcce9 100644
--- a/sd/source/filter/pdf/sdpdffilter.cxx
+++ b/sd/source/filter/pdf/sdpdffilter.cxx
@@ -65,9 +65,11 @@ bool SdPdfFilter::Import()
 
     // Add as many pages as we need up-front.
     mrDocument.CreateFirstPages();
+    sal_uInt16 nPageToDuplicate = 0;
     for (size_t i = 0; i < aGraphics.size() - 1; ++i)
     {
-        mrDocument.DuplicatePage(0);
+        // duplicating the last page is cheaper than repeatedly duplicating 
the first one
+        nPageToDuplicate = mrDocument.DuplicatePage(nPageToDuplicate);
     }
 
     for (vcl::PDFGraphicResult const& rPDFGraphicResult : aGraphics)
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index 46497f398944..8101e7ac0b96 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -133,8 +133,6 @@ SdrModel::SdrModel(SfxItemPool* pPool, 
comphelper::IEmbeddedHelper* pEmbeddedHel
     , m_bThemedControls(true)
     , mbUndoEnabled(true)
     , mbChanged(false)
-    , m_bPagNumsDirty(false)
-    , m_bMPgNumsDirty(false)
     , m_bTransportContainer(false)
     , m_bReadOnly(false)
     , m_bTransparentTextFrames(false)
@@ -1176,23 +1174,27 @@ void SdrModel::RecalcPageNums(bool bMaster)
 {
     if(bMaster)
     {
-        sal_uInt16 nCount=sal_uInt16(maMasterPages.size());
-        sal_uInt16 i;
-        for (i=0; i<nCount; i++) {
-            SdrPage* pPg = maMasterPages[i].get();
-            pPg->SetPageNum(i);
+        if (m_nMasterPageNumsDirtyFrom != SAL_MAX_UINT16)
+        {
+            sal_uInt16 nCount=sal_uInt16(maMasterPages.size());
+            for (sal_uInt16 i=m_nMasterPageNumsDirtyFrom; i<nCount; i++) {
+                SdrPage* pPg = maMasterPages[i].get();
+                pPg->SetPageNum(i);
+            }
+            m_nMasterPageNumsDirtyFrom = SAL_MAX_UINT16;
         }
-        m_bMPgNumsDirty=false;
     }
     else
     {
-        sal_uInt16 nCount=sal_uInt16(maPages.size());
-        sal_uInt16 i;
-        for (i=0; i<nCount; i++) {
-            SdrPage* pPg = maPages[i].get();
-            pPg->SetPageNum(i);
+        if (m_nPageNumsDirtyFrom != SAL_MAX_UINT16)
+        {
+            sal_uInt16 nCount=sal_uInt16(maPages.size());
+            for (sal_uInt16 i = m_nPageNumsDirtyFrom; i<nCount; i++) {
+                SdrPage* pPg = maPages[i].get();
+                pPg->SetPageNum(i);
+            }
+            m_nPageNumsDirtyFrom = SAL_MAX_UINT16;
         }
-        m_bPagNumsDirty=false;
     }
 }
 
@@ -1210,7 +1212,7 @@ void SdrModel::InsertPage(SdrPage* pPage, sal_uInt16 nPos)
     if (mbMakePageObjectsNamesUnique)
         pPage->MakePageObjectsNamesUnique();
 
-    if (nPos<nCount) m_bPagNumsDirty=true;
+    if (nPos<nCount) m_nPageNumsDirtyFrom = std::min(m_nPageNumsDirtyFrom, 
static_cast<sal_uInt16>(nPos + 1));
     SetChanged();
     SdrHint aHint(SdrHintKind::PageOrderChange, pPage);
     Broadcast(aHint);
@@ -1229,7 +1231,7 @@ rtl::Reference<SdrPage> SdrModel::RemovePage(sal_uInt16 
nPgNum)
     if (pPg) {
         pPg->SetInserted(false);
     }
-    m_bPagNumsDirty=true;
+    m_nPageNumsDirtyFrom = std::min(m_nPageNumsDirtyFrom, nPgNum);
     SetChanged();
     SdrHint aHint(SdrHintKind::PageOrderChange, pPg.get());
     Broadcast(aHint);
@@ -1259,7 +1261,7 @@ void SdrModel::InsertMasterPage(SdrPage* pPage, 
sal_uInt16 nPos)
     pPage->SetPageNum(nPos);
 
     if (nPos<nCount) {
-        m_bMPgNumsDirty=true;
+        m_nMasterPageNumsDirtyFrom = std::min(m_nMasterPageNumsDirtyFrom, 
static_cast<sal_uInt16>(nPos + 1));
     }
 
     SetChanged();
@@ -1291,7 +1293,7 @@ rtl::Reference<SdrPage> 
SdrModel::RemoveMasterPage(sal_uInt16 nPgNum)
         pRetPg->SetInserted(false);
     }
 
-    m_bMPgNumsDirty=true;
+    m_nMasterPageNumsDirtyFrom = std::min(m_nMasterPageNumsDirtyFrom, nPgNum);
     SetChanged();
     SdrHint aHint(SdrHintKind::PageOrderChange, pRetPg.get());
     Broadcast(aHint);
@@ -1308,7 +1310,7 @@ void SdrModel::MoveMasterPage(sal_uInt16 nPgNum, 
sal_uInt16 nNewPos)
         maMasterPages.insert(maMasterPages.begin()+nNewPos,pPg);
         MasterPageListChanged();
     }
-    m_bMPgNumsDirty=true;
+    m_nMasterPageNumsDirtyFrom = std::min(m_nMasterPageNumsDirtyFrom, 
std::min(nPgNum, nNewPos));
     SetChanged();
     SdrHint aHint(SdrHintKind::PageOrderChange, pPg.get());
     Broadcast(aHint);
@@ -1484,7 +1486,7 @@ void SdrModel::Merge(SdrModel& rSourceModel,
                     
maMasterPages.insert(maMasterPages.begin()+nDstMasterPageCnt, pPg);
                     MasterPageListChanged();
                     pPg->SetInserted();
-                    m_bMPgNumsDirty=true;
+                    m_nMasterPageNumsDirtyFrom = 
std::min(m_nMasterPageNumsDirtyFrom, nDstMasterPageCnt);
                     if (bUndo) 
AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pPg));
                 } else {
                     OSL_FAIL("SdrModel::Merge(): MasterPage not found in 
SourceModel.");
@@ -1567,8 +1569,8 @@ void SdrModel::Merge(SdrModel& rSourceModel,
     pMasterMap.reset();
     pMasterNeed.reset();
 
-    m_bMPgNumsDirty=true;
-    m_bPagNumsDirty=true;
+    m_nMasterPageNumsDirtyFrom = 0;
+    m_nPageNumsDirtyFrom = 0;
 
     SetChanged();
     // TODO: Missing: merging and mapping of layers

Reply via email to