[Libreoffice-commits] core.git: sc/inc sc/qa sc/source

Samuel Mehrbrodt Samuel.Mehrbrodt at cib.de
Wed Jan 31 13:34:33 UTC 2018


 sc/inc/drwlayer.hxx              |    4 ++--
 sc/qa/unit/ucalc_sort.cxx        |   10 ++++++----
 sc/source/core/data/column4.cxx  |   18 ++++++++++--------
 sc/source/core/data/drwlayer.cxx |   19 ++++++++++---------
 sc/source/core/data/table3.cxx   |   18 ++++++++----------
 5 files changed, 36 insertions(+), 33 deletions(-)

New commits:
commit ea607135ce6bb607508ac6ce6fcc4dae99f297a9
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Tue Jan 23 14:22:59 2018 +0100

    Improve performance when looking for draw objects anchored to cells
    
    Look for a whole column at once so we don't have to iterate all draw objects
    for every cell, but only once per column.
    
    Follow-up for 3a2a430ae8e2c1647c18d8904477949f6e2e7941
    
    Change-Id: Ic8740fca7d595528785b432c1cedf4fad4f13ba1
    Reviewed-on: https://gerrit.libreoffice.org/48416
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>

diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index d9155d0d90f0..92fc4f0449df 100644
--- a/sc/inc/drwlayer.hxx
+++ b/sc/inc/drwlayer.hxx
@@ -182,8 +182,8 @@ public:
     static void             SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab );
     static void             UpdateCellAnchorFromPositionEnd( const SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true );
     static ScAnchorType     GetAnchorType( const SdrObject& );
-    std::vector<SdrObject*> GetObjectsAnchoredToCell(const ScAddress& rPos);
-    bool                    HasObjectsAnchoredInRange(ScRange& rRange);
+    std::map<SCROW, std::vector<SdrObject*>> GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow);
+    bool HasObjectsAnchoredInRange(ScRange& rRange);
     void MoveObject(SdrObject* pObj, ScAddress& rNewPosition);
 
     // positions for detektive lines
diff --git a/sc/qa/unit/ucalc_sort.cxx b/sc/qa/unit/ucalc_sort.cxx
index eb7d1b79039e..e700c5e4ffe2 100644
--- a/sc/qa/unit/ucalc_sort.cxx
+++ b/sc/qa/unit/ucalc_sort.cxx
@@ -1921,8 +1921,9 @@ void Test::testSortImages()
     ScAddress aCellPos(1, 1, 0);
     pDrawLayer->MoveObject(pObj, aCellPos);
 
-    std::vector<SdrObject*> pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size());
+    std::map<SCROW, std::vector<SdrObject*>> pRowObjects
+        = pDrawLayer->GetObjectsAnchoredToRange(aCellPos.Tab(), aCellPos.Col(), aCellPos.Row(), aCellPos.Row());
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pRowObjects[aCellPos.Row()].size());
 
     ScSortParam aSortData;
     aSortData.nCol1 = 0;
@@ -1940,8 +1941,9 @@ void Test::testSortImages()
 
     // check that note is also moved after sorting
     aCellPos = ScAddress(1, 0, 0);
-    pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size());
+    pRowObjects
+        = pDrawLayer->GetObjectsAnchoredToRange(aCellPos.Tab(), aCellPos.Col(), aCellPos.Row(), aCellPos.Row());
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pRowObjects[aCellPos.Row()].size());
 
     m_pDoc->DeleteTab(0);
 }
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 14a5e89c2b54..d76b17496fb0 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1091,16 +1091,18 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, SCROW nRow2, bool bPattern )
     ScDrawLayer* pDrawLayer = GetDoc()->GetDrawLayer();
     if (pDrawLayer)
     {
+        std::map<SCROW, std::vector<SdrObject*>> aThisColRowDrawObjects
+            = pDrawLayer->GetObjectsAnchoredToRange(GetTab(), GetCol(), nRow1, nRow2);
+        std::map<SCROW, std::vector<SdrObject*>> aOtherColRowDrawObjects
+            = pDrawLayer->GetObjectsAnchoredToRange(GetTab(), rOther.GetCol(), nRow1, nRow2);
         for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
         {
-            ScAddress aThisCellPos(GetCol(), nRow, GetTab());
-            ScAddress aOtherCellPos(rOther.GetCol(), nRow, GetTab());
-            std::vector<SdrObject*> pThisColObjects = pDrawLayer->GetObjectsAnchoredToCell(aThisCellPos);
-            std::vector<SdrObject*> pOtherColObjects = pDrawLayer->GetObjectsAnchoredToCell(aOtherCellPos);
-            if (!pThisColObjects.empty())
-                UpdateDrawObjectsForRow(pThisColObjects, rOther.GetCol(), nRow);
-            if (!pOtherColObjects.empty())
-                rOther.UpdateDrawObjectsForRow(pOtherColObjects, GetCol(), nRow);
+            std::vector<SdrObject*>& rThisCellDrawObjects = aThisColRowDrawObjects[nRow];
+            if (!rThisCellDrawObjects.empty())
+                UpdateDrawObjectsForRow(rThisCellDrawObjects, rOther.GetCol(), nRow);
+            std::vector<SdrObject*>& rOtherCellDrawObjects = aOtherColRowDrawObjects[nRow];
+            if (!rOtherCellDrawObjects.empty())
+                rOther.UpdateDrawObjectsForRow(rOtherCellDrawObjects, GetCol(), nRow);
         }
     }
 
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 6ad031b952d7..311109a77115 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -1994,27 +1994,28 @@ ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj )
     return ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)) ? SCA_CELL : SCA_PAGE;
 }
 
-std::vector<SdrObject*> ScDrawLayer::GetObjectsAnchoredToCell(const ScAddress& rCell)
+std::map<SCROW, std::vector<SdrObject*>>
+ScDrawLayer::GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow)
 {
-    SdrPage* pPage = GetPage(static_cast<sal_uInt16>(rCell.Tab()));
+    SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
     if (!pPage || pPage->GetObjCount() < 1)
-        return std::vector<SdrObject*>();
+        return std::map<SCROW, std::vector<SdrObject*>>();
 
-    std::vector<SdrObject*> pObjects;
+    std::map<SCROW, std::vector<SdrObject*>> aRowObjects;
     SdrObjListIter aIter( *pPage, SdrIterMode::Flat );
     SdrObject* pObject = aIter.Next();
-    ScDrawObjData* pObjData;
+    ScRange aRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab);
     while (pObject)
     {
         if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently
         {
-            pObjData = GetObjData(pObject);
-            if (pObjData && pObjData->maStart == rCell) // Object is anchored to this cell
-                pObjects.push_back(pObject);
+            ScDrawObjData* pObjData = GetObjData(pObject);
+            if (pObjData && aRange.In(pObjData->maStart))
+                aRowObjects[pObjData->maStart.Row()].push_back(pObject);
         }
         pObject = aIter.Next();
     }
-    return pObjects;
+    return aRowObjects;
 }
 
 bool ScDrawLayer::HasObjectsAnchoredInRange(ScRange& rRange)
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 06c7b8919db4..d25bd8823319 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -433,6 +433,13 @@ void initDataRows(
 
         sc::ColumnBlockConstPosition aBlockPos;
         rCol.InitBlockPosition(aBlockPos);
+        std::map<SCROW, std::vector<SdrObject*>> aRowDrawObjects;
+        ScDrawLayer* pDrawLayer = rTab.GetDoc().GetDrawLayer();
+        if (pDrawLayer)
+            aRowDrawObjects = pDrawLayer->GetObjectsAnchoredToRange(rTab.GetTab(), nCol, nRow1, nRow2);
+        else
+            SAL_WARN("sc", "Could not retrieve anchored images, no DrawLayer available");
+
         for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
         {
             ScSortInfoArray::Row& rRow = *rRows[nRow-nRow1];
@@ -440,17 +447,8 @@ void initDataRows(
             rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
             rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
             rCell.mpNote = rCol.GetCellNote(aBlockPos, nRow);
-            ScDrawLayer* pDrawLayer = rTab.GetDoc().GetDrawLayer();
             if (pDrawLayer)
-            {
-                ScAddress aCellPos(nCol, nRow, rTab.GetTab());
-                std::vector<SdrObject*> pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
-                rCell.maDrawObjects = pObjects;
-            }
-            else
-            {
-                SAL_WARN("sc", "Could not retrieve anchored images, no DrawLayer available");
-            }
+                rCell.maDrawObjects = aRowDrawObjects[nRow];
 
             if (!bUniformPattern && bPattern)
                 rCell.mpPattern = rCol.GetPattern(nRow);


More information about the Libreoffice-commits mailing list