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 <[email protected]> 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 <[email protected]> Reviewed-by: Eike Rathke <[email protected]> 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); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
